1

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

ご覧のとおり、ソートはdate_validではなくid_variableで行われているようです。期待される結果を得るには、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 を指定した場合、または 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)
4

1 に答える 1

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 です

于 2014-07-11T09:45:25.990 に答える