中規模のRDSボックス(db.m3.medium、3.7gb ram)で非常に遅いクエリを取得しているようです。
これは、4,152,928行のテーブル全体です。
select sum(some_field) c
from pages
where pages.some_id=123
and pages.first_action_at > '2014-01-01 00:00:00 +1000'
合計実行時間:45031ミリ秒。
ローカルでは、約110万行あり、同じクエリには約450ミリ秒かかります。
これは、explainからのクエリプランです。
Aggregate (cost=475640.59..475640.60 rows=1 width=4)
-> Seq Scan on pages (cost=0.00..475266.07 rows=149809 width=4)
Filter: ((first_action_at > '2014-01-01 00:00:00'::timestamp without time zone)
AND (some_id = 447))
これは、explain analyzeからの応答です。
Aggregate (cost=475641.74..475641.76 rows=1 width=4) (actual time=42419.717..42419.718 rows=1 loops=1)
-> Seq Scan on pages (cost=0.00..475267.22 rows=149810 width=4) (actual time=0.013..42265.908 rows=141559 loops=1)
Filter: ((first_action_at > '2014-01-01 00:00:00'::timestamp without time zone) AND (some_id = 447))
Rows Removed by Filter: 4011369
合計実行時間:42419.772 ms
参考までに、141559行はsum()の一部です。
現在のインデックスは次のとおりです。
:some_id
:some_id, :first_action_at
work_mem
は、以前は1 MBに設定されていました(RDSのデフォルト)。これを18 MBに変更しました。
編集:work_mem
をアップして解決するようで、上記の2番目のインデックスを追加しました。速度は約800ミリ秒になりました。
あなたの質問をもう一度読んだ後、私はあなたがAmazon Redshiftを実行していないことに気づきましたが、Amazon RDSは、引き延ばされていないPostgresを実行しているようです、少なくとも ドキュメントによると :
Amazon RDSは、PostgreSQLのいくつかのバージョンを実行するDBインスタンスをサポートしています。現在、PostgreSQLバージョン9.3.1、9.3.2、9.3.3をサポートしています。
これは インデックスのみのスキャン を自由に使えることを意味します。いくつかの前提条件を満たしている場合(基本的にはvacuum
が書き込み操作に対応できる場合)、some_field
が頻繁に合理的に小さく更新されない場合(これは数値列の場合のようです)、完全なインデックスには、最後の位置にsome_field
が含まれます(最初に言及した @ zerkms など):
CREATE INDEX ON pages(some_id, first_action_at, some_field);
some_id
は、beforefirst_action_at
の前に来る必要があることに注意してください。 。詳細:
複数列のインデックスとパフォーマンス
EXPLAIN ANALYZE
に「インデックスのみのスキャン」が表示されない場合、最後の列はバラストであり、そのままにしておくことをお勧めします。
CREATE INDEX ON pages(some_id, first_action_at);
(あなたの質問の更新によると、あなたが今持っているように。)
どちらの方法でも、(some_id)
だけの別のインデックスは、この複数列のインデックスに対してほとんど提供しません。
複合インデックスは最初のフィールドのクエリにも適していますか?
すべての 遅いクエリと適切なサーバー構成のための通常のアドバイス が適用され、1 MBのwork_mem
設定は、数百万行のDBには低すぎます。ただし、work_mem
は( ドキュメントごと )であるため、この特定の設定はこの特定のクエリにとって重要ではありません。
内部ソート操作およびハッシュテーブルで使用されるメモリ。
ここではどちらも適用されません。