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