我不能相信我用帶有ORDER BY子句的簡單選擇看到的。 這裏是我的查詢和故障結果:Postgresql 9.2對索引字段的時間戳排序不會在一天內的小時部分排序
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
這裏是部分表定義,它partitionned上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,或者如果我用另一個選項包含在SELECT中,則結果相同(未排序):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)
PostgreSQL 9.2.0 –
我無法在9.1,9.2或9.3中重現此行爲。 –
[9.2.1修復:_Fix可能對涉及WHERE indexed_column IN(list_of_values)_ _(http://www.postgresql.org/docs/9.2/static/release-9-2-1.html ) –