2014-07-10 22 views
1

我不能相信我用帶有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) 
+0

PostgreSQL 9.2.0 –

+0

我無法在9.1,9.2或9.3中重現此行爲。 –

+4

[9.2.1修復:_Fix可能對涉及WHERE indexed_column IN(list_of_values)_ _(http://www.postgresql.org/docs/9.2/static/release-9-2-1.html ) –

回答

1

大概固定在9.2.1此錯誤

修正輸出的可能的不正確的排序從涉及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

+0

感謝您的幫助,但並未解決問題。更新到9.2.8,重新索引了所有的數據庫並仍然得到相同的結果。但是,這是一個很好的線索,就像我用「(id_variable = 11012或id_variable = 12004)」替換「id_variable IN(11012,12004)」一樣,順序是OK(在更新之前和之後測試)。 –

+0

@LeDroid更新後是否重新啓動服務器? –

+0

Postgresql服務器完全停止,但我沒有重新啓動硬件,因爲Postgresql沒有運行任何東西。你認爲這是必要的嗎? –