簡體   English   中英

將子查詢轉換為聯接查詢

[英]Convert subquery to join query

這是有效的MySQL查詢,是否可以將其轉換為單個平面連接查詢以提高性能? 而不是使用下面的子查詢。 謝謝

SELECT * from catAtt ca LEFT JOIN att a ON ca.attId = a.attId
WHERE ca.catId = 53 AND a.attCatId = 
(
SELECT DISTINCT eav.catId FROM ent LEFT JOIN eav ON ent.entId = eav.entId 
WHERE ent.key = 'somekey'
)

我將從簡化查詢開始。 由於where子句,您的兩個left join實際上都是內部連接。 同樣,子查詢中不需要select distinct分開。

select ca.*, att.*
from catAtt ca join
     att a 
     on ca.attId = a.attId 
where ca.catId = 53 and
      a.attCatId = (select eav.catId 
                    from ent join
                         eav 
                         on ent.entId = eav.entId 
                    where ent.key = 'somekey'
                   );

這建議使用索引: catAtt(catId, attId)att(attId, attCatId)ent(key, entId)eav(entId, catId)

您還可以將子查詢在wherefrom 我認為這不會對性能產生太大影響。 它不相關,因此只運行一次並返回一個值。

SELECT * from catAtt ca 
LEFT JOIN att a ON ca.attId = a.attId
INNER JOIN 
(
  SELECT DISTINCT eav.catId FROM ent 
  LEFT JOIN eav ON ent.entId = eav.entId 
  WHERE ent.key = 'somekey'
)Z ON a.attCatId = Z.catId 
WHERE ca.catId = 53 

嘗試上面的代碼。

希望這會幫助你。

我在sql服務器上嘗試了三種類型的查詢。

SELECT * from catAtt ca JOIN att a ON ca.attId = a.attId
WHERE ca.catId = 53 AND a.attCatId = 
(
SELECT DISTINCT eav.catId FROM ent LEFT JOIN eav ON ent.entId = eav.entId 
WHERE ent.key = 'somekey'
)

SELECT * from catAtt ca 
JOIN att a ON ca.attId = a.attId
JOIN 
(
  SELECT DISTINCT eav.catId FROM ent 
  LEFT JOIN eav ON ent.entId = eav.entId 
  WHERE ent.key = 'somekey'
)Z ON a.attCatId = Z.catId 
WHERE ca.catId = 53 

SELECT * from catAtt ca JOIN att a ON ca.attId = a.attId
WHERE ca.catId = 53 AND 
EXISTS 
   (
    SELECT 1 FROM ent LEFT JOIN eav ON ent.entId = eav.entId 
    WHERE ent.key = 'somekey' AND a.attCatId = eav.catId
   )

每個查詢的查詢成本是相同的33%。

猜數據庫比我們聰明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM