我需要幫助來重寫查詢以提高性能。products我認為下面的查詢很慢,因為 OR 部分和表中每個鍵的兩個子查詢(所以兩次掃描) category。
SELECT key
FROM category c
WHERE (1=1)
AND ( ((EXISTS (SELECT * from products p
WHERE p.attribute_key=2
AND p.category_key=c.key
AND ((value && CAST(ARRAY['Active', 'active'] AS text[])))
AND p.status='active'
))
OR(NOT EXISTS(SELECT * from products p
WHERE p.attribute_key=2
AND p.category_key=c.key
AND p.status='active')
))
)
AND c.status='active'
AND c.type_key=4
預期輸出為(9 行)以下
key
1
13
3
6
2
7
4
10
15
如果 type_key=4 和 category.status='active' 和
products 表的 value='Active' 或 'active' 并且 attribute_key=2 和 status='active。(這是
EXISTS查詢的一部分)即使產品表沒有任何屬性鍵或屬性鍵!= 2 記錄 type_key=4。(這是
OR( NOT EXISTS)查詢的一部分)示例:type_key 13 和 3
查詢解釋分析計劃如下。索引使用得很好。
我希望可以通過撰寫另一種方式或更改查詢中的 OR 部分來改進查詢
樣本資料在這里dbfiddle
Aggregate (cost=3156220.03..3156220.04 rows=1 width=8) (actual time=86100.329..86100.342 rows=1 loops=1)
-> Index Scan using category_type_key_status on category c (cost=0.43..3155906.64 rows=125355 width=0) (actual time=12.618..85925.747 rows=120852 loops=1)
Index Cond: ((type_key = 4) AND (status = 'active'))
Filter: ((alternatives: SubPlan 1 or hashed SubPlan 2) OR (NOT (SubPlan 3)))
Rows Removed by Filter: 86879
SubPlan 1
-> Index Scan using products_category_key_attribute_key_status on products p (cost=0.56..8.59 rows=1 width=0) (actual time=0.332..0.332 rows=1 loops=207731)
Index Cond: ((category_key = c.key) AND (attribute_key = 2) AND (status = 'active'))
Filter: (value && '{Active,active}'::text[])
Rows Removed by Filter: 0
SubPlan 2
-> Gather (cost=1000.00..1155110.30 rows=8916 width=4) (never executed)
Workers Planned: 2
Workers Launched: 0
-> Parallel Seq Scan on products p_1 (cost=0.00..1153218.70 rows=3715 width=4) (never executed)
Filter: ((value && '{Active,active}'::text[]) AND (attribute_key = 2) AND (status = 'active'))
SubPlan 3
-> Index Only Scan using products_category_key_attribute_key_status on products p_2 (cost=0.56..8.58 rows=1 width=0) (actual time=0.008..0.008 rows=1 loops=86933)
Index Cond: ((category_key = c.key) AND (attribute_key = 2) AND (status = 'active'))
Heap Fetches: 11497
Planning Time: 35.808 ms
Planning Time: 35.808 ms
uj5u.com熱心網友回復:
products 表上的兩個謂詞幾乎完全相同。您可以簡單地加入此表一次并使用 OR 來應用任一條件:
SELECT c.key
FROM category c
LEFT OUTER
JOIN products p
ON p.category_key = c.key
AND p.status = 'active'
AND p.attribute_key = 2
WHERE c.status='active'
AND c.type_key=4
AND ( p.category_key IS NULL -- NOT EXISTS
OR ((value && CAST(ARRAY['Active', 'active'] AS text[])))) -- or value matches
帶有結果的 dbfiddle
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/444779.html
標籤:PostgreSQL 存在 postgresql 性能 在哪里 不存在
