MySQL更新加入选择非常慢

时间:2014-06-18 21:21:52

标签: mysql sql sql-update inner-join database-performance

我们有一个存储过程,用于为报告准备数据。请注意,架构并不像它应该的那样规范化,但它就是它,我们无法修改它,因此为报告构建临时表。 MySQL版本是5.1.70。

有一个更新语句将临时表从连接更新为选择。请注意,此查询中应具有索引的所有列都包括,包括临时表(OI):

UPDATE `tmpOrderInquiry` OI
INNER JOIN (
SELECT `SalesOrderNo`, 
    GROUP_CONCAT(Inv.`InvoiceNo` ORDER BY `InvoiceNo` ASC SEPARATOR '~|~') as `InvoiceNoGRP`, 
    GROUP_CONCAT(DATE_FORMAT(date(`ShipDate`), ' %c/%d/%y') ORDER BY `ShipDate` ASC SEPARATOR '~|~') as `ShipDateGRP`,
    GROUP_CONCAT(DATE_FORMAT(date(`LastPmtDate`), ' %c/%d/%y') ORDER BY `LastPmtDate` ASC SEPARATOR '~|~') as `LastPmtDateGRP`
    FROM `InsynchInvoiceHistoryHeader` Inv 
    GROUP BY Inv.`SalesOrderNo`
    ) as OrdInv ON OI.`SalesOrderNo` = OrdInv.`SalesOrderNo`
SET OI.`InvoiceNo` = OrdInv.`InvoiceNoGRP`, OI.`ShipDate` = OrdInv.`ShipDateGRP`, OI.`LastPmtDate` = OrdInv.`LastPmtDateGRP`

此查询平均需要大约70秒才能完成。 select本身执行sub-second。经过多次敲击后,我用一条云雀替换了上面的:

CREATE TEMPORARY TABLE `tempWorking` AS SELECT 
    `SalesOrderNo`, 
        GROUP_CONCAT(Inv.`InvoiceNo` ORDER BY `InvoiceNo` ASC SEPARATOR '~|~') as `InvoiceNoGRP`, 
        GROUP_CONCAT(DATE_FORMAT(date(`ShipDate`), ' %c/%d/%y') ORDER BY `ShipDate` ASC SEPARATOR '~|~') as `ShipDateGRP`,
        GROUP_CONCAT(DATE_FORMAT(date(`LastPmtDate`), ' %c/%d/%y') ORDER BY `LastPmtDate` ASC SEPARATOR '~|~') as `LastPmtDateGRP`
        FROM `InsynchInvoiceHistoryHeader` Inv 
        GROUP BY Inv.`SalesOrderNo`;
UPDATE `tmpOrderInquiry` OI
INNER JOIN tempWorking as OrdInv ON OI.`SalesOrderNo` = OrdInv.`SalesOrderNo`
SET OI.`InvoiceNo` = OrdInv.`InvoiceNoGRP`, OI.`ShipDate` = OrdInv.`ShipDateGRP`, OI.`LastPmtDate` = OrdInv.`LastPmtDateGRP`

此查询在大约2秒内运行。由于选择本身很快,我无法解释为什么第一个查询太慢了。因为问题很严重我把这个改变发布到了生产中,但是我不喜欢引入一个所有条件相同的修复程序,我希望实际上会让事情变得更慢。

有关第一次更新声明为何如此缓慢的任何见解将不胜感激。

0 个答案:

没有答案