1100万レコードの大きなテーブルがあります。レコードを1枚手に入れたい。
SELECT *
FROM "PRD".events_log
WHERE plc_time < '2012-11-19 14:00'
AND ((event_type_id IN (1,51)
AND machine_id = 1
AND island_id = 88)
OR (event_type_id IN (2000,2001)
AND machine_id=88))
ORDER BY plc_time desc
LIMIT 1
両側で plc_time を制限していないため、このクエリを注文するコストは大きくなります。これを制限することはできないので、これを高速化できますか?
私は重要なフィールドにインデックスを持っているので、それがないことは問題になりません。
このクエリは、関数 pl/pgsql の他のクエリの 1 つです。
カーソルについて聞いたことがありますが、どのように使用すればよいかわかりません。
これは、このクエリを分析する説明です:
「制限 (コスト=4719.97..4719.97 行=1 幅=850) (実際の時間=6074.900..6074.901 行=1 ループ=1)」 " -> 並べ替え (コスト = 4719.97..4720.49 行 = 208 幅 = 850) (実際の時間 = 6074.897..6074.897 行 = 1 ループ = 1)" " ソートキー: plc_time" 「ソート方法:トップNヒープソート メモリ:17kB」 " -> events_log のビットマップ ヒープ スキャン (コスト = 50.07..4718.93 行 = 208 幅 = 850) (実際の時間 = 248.306..6068.046 行 = 6911 ループ = 1)" " 条件を再確認: (((machine_id = 1) AND (event_type_id = ANY ('{1,51}'::integer[]))) OR ((machine_id = 88) AND (event_type_id = ANY ('{2000,2001 }'::整数[]))))" " フィルタ: ((plc_time BitmapOr (cost=50.07..50.07 rows=1246 width=0) (actual time=244.710..244.710 rows=0 loops=1)" " -> fki_events_type_fk のビットマップ インデックス スキャン (コスト = 0.00..24.98 行 = 623 幅 = 0) (実際の時間 = 238.529..238.529 行 = 832699 ループ = 1)" " インデックス条件: ((machine_id = 1) AND (event_type_id = ANY ('{1,51}'::integer[])))" " -> fki_events_type_fk のビットマップ インデックス スキャン (コスト = 0.00..24.98 行 = 623 幅 = 0) (実際の時間 = 6.177..6.177 行 = 6869 ループ = 1)" "インデックス条件: ((machine_id = 88) AND (event_type_id = ANY ('{2000,2001}'::integer[])))" 「合計実行時間: 6075.175 ミリ秒」
そしてテーブルを分析します:
INFORMACJA: analizowanie "PRD.events_log" INFORMACJA: "events_log": przeskanowano 30000 z 158056 stron, zawierających 2369701 żywych wierszy i 71270 martwych wierszy; 30000 wierszy w przykładzie, 12488167 szacowanych wszystkich wierszy Zapytanie zostało wykonane w 52203 ms i nie zwróciło żadnych wyników. 高速翻訳: 158056 ページから 3000 をスキャン: 2369701 の有効な行と 71270 の無効な行。 例では 30000 行、12488167 はすべての行を見積もった