Postgresql

跨連接進行 ORing 時 Postgres 不使用索引

  • April 19, 2018

我正在對兩個表進行連接查詢,我需要在每個表中的欄位上執行 ILIKE 過濾器,兩端都帶有萬用字元,如果它們中的任何一個匹配,它應該返回一行。

大約:

SELECT * FROM "tableA" LEFT OUTER JOIN "tableB" ON 
"tableA"."tableB_id" = "tableB"."id" 
WHERE "tableA"."name" ILIKE '%rich%' OR "tableB"."name" ILIKE '%rich%';

由於這兩個表都很大,我決定嘗試使用三元組索引來加快速度。但是,這似乎沒有幫助,並且在進行了 EXPLAIN ANALYZE 之後,我發現沒有使用索引。如果過濾器與 AND 而不是 OR 組合使用,則使用它們,如果我在同一個表中的兩個索引列之間執行 OR,而不是在不同表中的索引列之間執行 OR,則使用它們。

任何人有任何想法為什麼?

有時將帶有OR條件的查詢重寫為UNION( ALL) 查詢很有用。這通常會導致可能更有效的不同執行計劃。測試將確定兩種方法/計劃中的哪一種在每種情況下更有效(例如,如果三元索引用於聯合的兩個部分)。

重寫:

SELECT * 
FROM "tableA" AS a 
   LEFT OUTER JOIN "tableB" AS b
   ON a."tableB_id" = b."id" 
WHERE a."name" ILIKE '%rich%'

UNION ALL

SELECT * 
FROM "tableA" AS a 
   INNER JOIN "tableB" AS b
   ON a."tableB_id" = b."id" 
WHERE b."name" ILIKE '%rich%'
 AND (a."name" IS NULL OR a."name" NOT ILIKE '%rich%')
;

引用自:https://dba.stackexchange.com/questions/204349