2013-12-17 94 views
0

大家好冠軍在那裏提高性能的MySQL查詢

我遠離大師,當涉及到高性能的SQL查詢和奇觀中的任何人都可以幫助我提高下面的查詢。它可以工作,但需要很長時間,特別是因爲我可以在IN()部分中有100個左右的條目。

代碼如下,希望你能夠找出足夠的幫助模式。

SELECT inv.amount 
FROM invoice inv 
WHERE inv.invoiceID IN (
     SELECT childInvoiceID 
     FROM invoiceRelation ir 
       LEFT JOIN Payment pay ON pay.invoiceID = ir.parentInvoiceID 
     WHERE pay.paymentID IN (125886, 119293, 123497)) 
+0

您的表是否在查詢的WHERE部分的列上有索引? – Jakob

+0

這是一個內部加入 – Strawberry

回答

3

重構您的查詢以使用聯接而不是子查詢。此外,使用INNER JOIN而不是LEFT JOIN到付款表。這是有道理的,因爲你有一個WHERE過濾器,無論如何都會在Payment表中過濾沒有匹配的行。

SELECT inv.amount 
FROM invoice inv 
INNER JOIN invoiceRelation ir ON inv.incoiceID = ir.childInvoiceID 
INNER JOIN Payment pay on pay.invoiceID = ir.parentInvoiceID 
WHERE pay.paymentID IN (...) 
+0

哇有什麼區別。從380毫秒到0.4毫秒。也感謝你對解決方案的解釋,幫助我理解。謝謝丹。 –

0

我認爲,而不是第一個in你可以使用內部連接。

select inv.amount from invoice inv 
inner join invoiceRelation ir on (inv.invoiceID = ir.childInvoiceID) 
LEFT JOIN Payment pay ON pay.invoiceID = ir.parentInvoiceID 
WHERE pay.paymentID IN (125886,119293,123497) 
2

提高性能的一種方法是在相關列上有一個很好的索引。在您的示例中,inv.invoiceI D上的索引可能會加快查詢的速度。

同樣在pay.paymentID

試試這個,看看是否有幫助:

ALTER TABLE invoice ADD INDEX invoiceID_idx (invoiceID); 

ALTER TABLE Payment ADD INDEX paymendID_idx (paymentID); 
+0

+1大多數時候,索引對於提高選擇的性能來說是最重要的。 –

+0

是的,我有索引那裏,但我想我的查詢沒有使用他們,由於巨大的where子句。現在他們工作:-)謝謝Jakob。 –

0

如果你嘗試喜歡這個代替:

SELECT inv.amount 
FROM invoice inv 
inner join invoiceRelation ir on inv.invoiceID = ir.parentInvoiceID 
left join Payment pay on pay.invoiceID = ir.parentInvoiceID 
WHERE pay.paymentID IN (125886, 119293, 123497) 

( OR)bette R等如果您確定付款表中有invoiceID FK,請將left join設置爲inner join

簡而言之,如果您可以將該子查詢替換爲聯接,則應始終嘗試避免相關子查詢。

+0

無論哪種方式,這是一個內部聯接 – Strawberry