2017-11-10 8 views
0

"mviews_price2"Postgresqlのスロークエリ

id     - Integer 
price    - Integer 
price2   - Integer 
unit_price  - Integer 
location_site_id - Integer 
leave_site_id - Integer 
web    - Boolean 
category_id  - Integer 

は、索引の作成マテリアライズド・ビューを作成します。

CREATE INDEX "location_site_id_idx" ON "mviews_price2" ("location_site_id") 
CREATE INDEX "leave_site_id_idx" ON "mviews_price2" ("leave_site_id") 
CREATE INDEX "web_idx" ON "mviews_price2" ("web") 

取得クエリを:

SELECT DISTINCT "mviews_price2"."category_id" FROM "mviews_price2" WHERE ("mviews_price2"."location_site_id" = 1 OR "mviews_price2"."leave_site_id" = 1 OR "mviews_price2"."web" = true) 

は説明:

HashAggregate (cost=42757.45..42757.82 rows=37 width=4) (actual time=596.252..596.257 rows=37 loops=1)' 
Group Key: category_id' 
-> Seq Scan on mviews_price2 (cost=0.00..39614.90 rows=1257021 width=4) (actual time=0.038..362.877 rows=1341021 loops=1)' 
     Filter: ((location_site_id = 1) OR (leave_site_id = 1) OR web)' 
     Rows Removed by Filter: 423439' 
Planning time: 0.954 ms' 
Execution time: 596.311 ms' 
ビューで本の

から1764460ライン

質問:

  1. はそれがインデックスを使用していないのはなぜ?
  2. クエリが非常に遅いのはなぜですか?

答えて

0

ORは、最適化するのが非常に難しいです。代わりにUNIONを使用してクエリを書いてみます

SELECT "mviews_price2"."category_id" 
FROM "mviews_price2" 
WHERE "mviews_price2"."location_site_id" = 1 
UNION -- on purpose to remove duplicates 
SELECT "mviews_price2"."category_id" 
FROM "mviews_price2" 
WHERE "mviews_price2"."leave_site_id" = 1 
UNION -- on purpose to remove duplicates 
SELECT "mviews_price2"."category_id" 
FROM "mviews_price2" 
WHERE "mviews_price2"."web" = true; 

各サブクエリは、指標の一つを利用することができるはずです。

注:これは依然としてクエリの速度を上げることはできません。 webのインデックスは、特に2つの値を持つフィールドの1つです(または、NULLをとることができる場合は3)。 webが非常にまれでない限り、結果はおそらくフルテーブルスキャンになります。

+0

3つの列すべてに単一のインデックスを付けると役立つでしょうか?私はそれがANDのために働くと確信していますか、または達成するのが簡単な制約ではないでしょうか? – cplusplusrat

+0

@plusplusrat。 。 。いいえ。「または」を指定すると、索引の最初のキーのみが使用されます。 –

関連する問題