いくつかの数値といくつかの追加データを含むPostgreSQL 9.3テーブルがあります。
CREATE TABLE mytable (
myid BIGINT,
somedata BYTEA
)
このテーブルには現在約1,000万のレコードがあり、1GBのディスク容量を使用します。myid
連続していません。
100000の連続番号の各ブロックにある行の数を計算したいと思います。
SELECT myid/100000 AS block, count(*) AS total FROM mytable GROUP BY myid/100000;
これは約3500行を返します。
クエリプランでまったく言及されていなくても、特定のインデックスが存在すると、このクエリが大幅に高速化されることに気づきました。インデックスなしのクエリプラン:
db=> EXPLAIN (ANALYZE TRUE, VERBOSE TRUE) SELECT myid/100000 AS block, count(*) AS total FROM mytable GROUP BY myid/100000;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------
GroupAggregate (cost=1636639.92..1709958.65 rows=496942 width=8) (actual time=6783.763..8888.841 rows=3460 loops=1)
Output: ((myid / 100000)), count(*)
-> Sort (cost=1636639.92..1659008.91 rows=8947594 width=8) (actual time=6783.752..8005.831 rows=8947557 loops=1)
Output: ((myid / 100000))
Sort Key: ((mytable.myid / 100000))
Sort Method: external merge Disk: 157440kB
-> Seq Scan on public.mytable (cost=0.00..236506.92 rows=8947594 width=8) (actual time=0.020..1674.838 rows=8947557 loops=1)
Output: (myid / 100000)
Total runtime: 8914.780 ms
(9 rows)
インデックス:
db=> CREATE INDEX myindex ON mytable ((myid/100000));
db=> VACUUM ANALYZE;
新しいクエリプラン:
db=> EXPLAIN (ANALYZE TRUE, VERBOSE TRUE) SELECT myid/100000 AS block, count(*) AS total FROM mytable GROUP BY myid/100000;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
HashAggregate (cost=281242.99..281285.97 rows=3439 width=8) (actual time=3190.189..3190.800 rows=3460 loops=1)
Output: ((myid / 100000)), count(*)
-> Seq Scan on public.mytable (cost=0.00..236505.56 rows=8947485 width=8) (actual time=0.026..1659.571 rows=8947557 loops=1)
Output: (myid / 100000)
Total runtime: 3190.975 ms
(5 rows)
したがって、クエリプランとランタイムは大幅に(ほぼ3倍)異なりますが、どちらもインデックスについては言及していません。この動作は、私の開発マシンで完全に再現可能です。インデックスを削除し、クエリを数回テストし、インデックスを再作成し、再度クエリを数回テストするというサイクルを数回行いました。ここで何が起こっているのですか?
explain (analyze true, verbose true) ...
か?
HashAggregate
メソッドにインデックスが使用されている(そしてソートが不要)と思います。これにより、パフォーマンスが向上します。なぜインデックスが計画に記載されていないのか、私には手掛かりがありません。