2017-11-10 169 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' 

在View - 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個值的字段(如果可以採用NULL,則爲3)。除非web非常罕見,否則結果可能仍然是全表掃描。

+0

對所有3列有單一索引有幫助嗎?我相信它適用於AND,不會是一個更容易實現的限制嗎? – cplusplusrat

+0

@cplusplusrat。 。 。不,使用'或'只會使用索引中的第一個鍵。 –