提高mySQL查询的性能

提高mySQL查询的性能,mysql,sql,Mysql,Sql,大家好 在高性能SQL查询方面,我远不是专家,我想知道有谁能帮我改进下面的查询。它可以工作,但需要的时间太长,特别是因为在in()部分中可以有100个左右的条目 代码如下,希望您能找出足够的模式来帮助 SELECT inv.amount FROM invoice inv WHERE inv.invoiceID IN ( SELECT childInvoiceID FROM invoiceRelation ir L

大家好

在高性能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 ) )

重新构造查询以使用联接而不是子选择。另外,对付款表使用内部联接,而不是左联接。这是合理的,因为您有一个WHERE过滤器,它可以过滤付款表中不匹配的行

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 (...)

重新构造查询以使用联接而不是子选择。另外,对付款表使用内部联接,而不是左联接。这是合理的,因为您有一个WHERE过滤器,它可以过滤付款表中不匹配的行

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 (...)

我认为可以使用内部联接,而不是在中使用第一个

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)

我认为可以使用内部联接,而不是在
中使用第一个

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)

提高性能的一种方法是在相关列上有一个良好的索引。在您的示例中,
inv.invoiceI
D上的索引可能会大大加快查询速度

同样在
pay.paymentID上

试试这个,看看是否有帮助:

ALTER TABLE invoice ADD INDEX invoiceID_idx (invoiceID);


提高性能的一种方法是在相关列上有一个良好的索引。在您的示例中,
inv.invoiceI
D上的索引可能会大大加快查询速度

同样在
pay.paymentID上

试试这个,看看是否有帮助:

ALTER TABLE invoice ADD INDEX invoiceID_idx (invoiceID);


如果您尝试这样做会怎么样:

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 )  
(或)更好;如果您确定在付款表中有invoiceID FK,则将该
左联接
设置为
内部联接


简而言之,如果可以将相关子查询替换为联接,则应始终避免相关子查询。

如果您尝试这样做,会怎么样:

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 )  
(或)更好;如果您确定在付款表中有invoiceID FK,则将该
左联接
设置为
内部联接


简而言之,如果可以将相关子查询替换为联接,则应始终避免相关子查询。

表在查询的WHERE部分的列上是否有索引?这是一个内部联接表在查询的WHERE部分的列上是否有索引?大多数情况下,这是一个内部联接+1,索引对于提高selects的性能是最重要的。是的,我有索引,但我想我的查询没有使用它们,因为where子句很大。现在它们工作了:-)谢谢Jakob。+1大多数时候,索引对于提高selects的性能是最重要的。是的,我在那里有索引,但我想我的查询没有使用它们,因为有一个巨大的where子句。现在他们开始工作了:-)谢谢雅各布。无论哪种方式,这都是一种内在的结合。无论哪种方式,这都是一种内在的结合。哇,多么不同啊。从380毫秒到0.4毫秒。也感谢您对解决方案的解释,帮助我理解。谢谢你,丹。哇,真不一样。从380毫秒到0.4毫秒。也感谢您对解决方案的解释,帮助我理解。谢谢你,丹。