索引字段上的 Postgresql 9.2 时间戳排序不会在一天内按小时部分排序

标签 postgresql sorting timestamp postgresql-9.2 partition

我不敢相信我看到的带有 ORDER BY 子句的简单选择。 这是我的查询和错误的结果:

SELECT date_valid, id_variable FROM myTable
   WHERE id_stn='78224' AND date_valid BETWEEN '2014-07-03 09:00:00'
         AND '2014-07-03 21:00:00' AND id_variable IN (11012,12004)
   ORDER BY date_valid ;

     date_valid      | id_variable 
---------------------+-------------
 2014-07-03 09:00:00 |       11012
 2014-07-03 15:00:00 |       11012
 2014-07-03 21:00:00 |       11012
 2014-07-03 09:00:00 |       12004
 2014-07-03 15:00:00 |       12004
 2014-07-03 21:00:00 |       12004

如您所见,排序似乎是在 id_variable 而不是 date_valid 上完成的。为了获得预期的结果,我必须创建一个 Postgresql 无法优化的新字段或提供超过 1 天的时间戳范围:

SELECT date_valid,id_variable FROM myTable
       WHERE id_stn='78224' AND date_valid BETWEEN '2014-07-03 09:00:00'
             AND '2014-07-03 21:00:00' AND id_variable IN (11012,12004)
       ORDER BY date_valid + '0 hours'::INTERVAL;

     date_valid      | id_variable
---------------------+-------------
 2014-07-03 09:00:00 |       11012
 2014-07-03 09:00:00 |       12004
 2014-07-03 15:00:00 |       11012
 2014-07-03 15:00:00 |       12004
 2014-07-03 21:00:00 |       11012
 2014-07-03 21:00:00 |       12004

这是一个部分表定义,它按每个月的 date_valid 进行分区:

    Column     |            Type
---------------+-----------------------------
 id_obs        | bigint                      
 date_valid    | timestamp without time zone
 id_variable   | integer
 id_stn        | character varying(50)
Indexes:
    "myTable_pkey" PRIMARY KEY, btree (id_obs)
    "myTable_ukey" UNIQUE CONSTRAINT, btree (date_valid, id_variable, lat, lon)
Check constraints:
    "myTable_date_valid_check" CHECK (date_valid >= '2014-07-01 00:00:00'::timestamp without time zone AND date_valid < '2014-08-01 00:00:00'::timestamp without time zone)
Triggers:
    myTable_before_update BEFORE UPDATE ON myTable_201407 FOR EACH ROW EXECUTE PROCEDURE obs_update()
Inherits: myTable_parent
Has OIDs: no

如果结果是在同一天,Postgresql 不会按小时排序,这似乎是一个错误。这一定是优化器问题,因为如果我在另一个未编制索引的时间戳字段上排序,我不会遇到这个问题。如果我在每个日期字符串之后指定::TIMESTAMP,或者如果我将选择包含在另一个 on 上,结果是相同的(未排序):SELECT * FROM (SELECT ...) x ORDER BY DATE_VALID。我对其他结构相似的表也有同样的问题。

这是 Postgresql 9.2.8 的 EXPLAIN 结果:

 Result  (cost=0.02..62864.86 rows=10 width=87)
   ->  Merge Append  (cost=0.02..62864.86 rows=10 width=87)
         Sort Key: myTable.date_valid
         ->  Sort  (cost=0.01..0.02 rows=1 width=220)
               Sort Key: myTable.date_valid
               ->  Seq Scan on myTable  (cost=0.00..0.00 rows=1 width=220)
                     Filter: ((date_valid >= '2014-07-03 09:00:00'::timestamp without time zone) AND (date_valid <= '2014-07-03 21:00:00'::timestamp without time zone) AND (id_variable = ANY ('{11012,12004}'::integer[])) AND ((id
_stn)::text = '78224'::text))
         ->  Index Scan using myTable_201407_ukey on myTable_201407 myTable  (cost=0.00..62864.71 rows=9 width=72)
               Index Cond: ((date_valid >= '2014-07-03 09:00:00'::timestamp without time zone) AND (date_valid <= '2014-07-03 21:00:00'::timestamp without time zone) AND (id_variable = ANY ('{11012,12004}'::integer[])))
               Filter: ((id_stn)::text = '78224'::text)

最佳答案

可能这个错误在 9.2.1 中修复了

Fix possible incorrect sorting of output from queries involving WHERE indexed_column IN (list_of_values)

http://www.postgresql.org/docs/9.2/static/release-9-2-1.html

9.2 已经是 9.2.8

关于索引字段上的 Postgresql 9.2 时间戳排序不会在一天内按小时部分排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24687898/

相关文章:

linux - 为什么 PostgreSQL 在执行长时间运行的 INSERT … SELECT … 时不保存到磁盘?

java - 按字母顺序排序数组列表时遇到问题

postgresql - 在子查询返回的每一行上调用一个函数

mysql - 按关联模型中的列对 Rails 数据库表进行排序

java - Spring Data JpaRepository findAll(Iterable<ID> ids) + findAll(Sort 排序)

javascript - [PHP][MySQL] 记录 60 秒后删除表

java - JDBC MySQL 读写 TIMESTAMP 自 Unix Epoch 以来的毫秒数

c# - 将 UNIX 时间格式的 UTC 时间转换为可读的 DateTime 格式?

sql - 使用生成的 UUID 更新列

sql - Crystal 报表 : Boolean Issues