Heroku "Crane" PostgreSQL インスタンスの実行 (バージョン 9.1.6)
販売ポイントのテーブルがあります。通貨金額は現地通貨です。特定の日の各通貨とユーロの間の換算係数を含む通貨換算表があります。特定の本 (製品) の売上、返品、プレゼント、収益 (ドル単位) を合計したいと考えています。そのため、現地通貨をユーロに変換するために通貨変換テーブルに参加し、再びユーロをドルに変換します (レートは売却の決済日に基づいて異なることに注意してください)。したがって、考慮されるすべての販売ポイントは、通貨換算に 2 回結合されます。実験により、それが主な速度低下要因であることがわかりました。
だから私は次のクエリを最適化しようとしています:
SELECT
sum(paid_sales - paid_returns) as paid_units,
sum(royalty_amt*(uu_cc.rate / sp_cc.rate)) as royalty_amt,
sum(free_sales - free_returns) as free_units,
sum(lent_units) as lent_units
FROM "sales_points"
join currency_conversions sp_cc
on sp_cc.date = sales_points.settlement_date
and sp_cc.currency = sales_points.currency
join currency_conversions uu_cc
on uu_cc.date = sales_points.settlement_date
and uu_cc.currency = 'USD'
WHERE "sales_points"."book_id" = 234
LIMIT 1
次のインデックスを作成しました。
CREATE INDEX index_currency_conversions_on_date_and_currency
ON currency_conversions
USING btree (date, currency COLLATE pg_catalog."default");
それでも、EXPLAIN (ANALYZE の実行後) は、通貨変換テーブルのシーケンシャル スキャンを行っていることを教えてくれます。重要な場合date
、タイプは「日付」でcurrency
あり、タイプは「char var(255)」です。
クエリプランは次のとおりです。
Limit (cost=7285.04..7285.04 rows=1 width=39) (actual time=103.166..103.167 rows=1 loops=1)
Buffers: shared hit=916
-> Aggregate (cost=7285.04..7285.04 rows=1 width=39) (actual time=103.163..103.163 rows=1 loops=1)
Buffers: shared hit=916
-> Hash Join (cost=584.15..7256.29 rows=6388 width=39) (actual time=60.513..92.084 rows=5840 loops=1)
Hash Cond: (sp_cc.date = uu_cc.date)
Buffers: shared hit=916
-> Hash Join (cost=351.63..6985.45 rows=6388 width=39) (actual time=52.454..72.418 rows=5840 loops=1)
Hash Cond: ((sales_points.settlement_date = sp_cc.date) AND ((sales_points.currency)::text = (sp_cc.currency)::text))
Buffers: shared hit=763
-> Bitmap Heap Scan on sales_points (cost=54.09..6630.06 rows=6446 width=30) (actual time=0.912..7.020 rows=5840 loops=1)
Recheck Cond: (book_id = 234)
Buffers: shared hit=610
-> Bitmap Index Scan on index_sales_points_on_book_id (cost=0.00..53.77 rows=6446 width=0) (actual time=0.809..0.809 rows=6521 loops=1)
Index Cond: (book_id = 234)
Buffers: shared hit=22
-> Hash (cost=214.95..214.95 rows=20649 width=16) (actual time=51.502..51.502 rows=20649 loops=1)
Buckets: 4096 Batches: 1 Memory Usage: 968kB
Buffers: shared hit=153
-> Seq Scan on currency_conversions sp_cc (cost=0.00..214.95 rows=20649 width=16) (actual time=0.007..21.153 rows=20649 loops=1)
Buffers: shared hit=153
-> Hash (cost=225.27..225.27 rows=2071 width=12) (actual time=8.040..8.040 rows=2071 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 89kB
Buffers: shared hit=153
-> Seq Scan on currency_conversions uu_cc (cost=0.00..225.27 rows=2071 width=12) (actual time=0.021..5.963 rows=2071 loops=1)
Filter: ((currency)::text = 'USD'::text)
Buffers: shared hit=153
Total runtime: 103.306 ms
私のインデックスを使用していない理由を誰かが知っていますか?