2017-06-22 64 views
1

這是工作的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' 
) 

回答

2

我會從簡化查詢開始。由於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)

您還可以將where中的子查詢移動到from。我認爲這不會對性能產生太大影響。它不相關,所以它運行一次,並返回一個值。

+0

好的,謝謝你指出內連接和左連接,我一直在使用左連接,不必忘記它的目的。所以我認爲沒有辦法讓查詢進入一個單一的查詢。謝謝。我會將此標記爲糾正缺陷的答案。 – William

0
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 

試試上面的代碼。

希望這會幫助你。

+0

這是否會改善性能? – Pasetchnik

+1

你檢查了索引嗎?索引的存在對連接或子查詢的順序影響更大。數據庫引擎通常會對連接和子查詢進行重新排序以優化性能,但如果缺少必需的索引,則無法優化任何內容。 –

0

我試過三種查詢在sql server上。

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%。

猜測DataBase比我們聰明。

+0

有趣的是,即使是第三個查詢在執行計劃中有「獨特排序」。 – Pasetchnik