MySQL查询非常慢(20到60秒!) - 为什么?

时间:2016-11-19 07:15:58

标签: php mysql apache performance

我遇到以下问题的问题。它从数据库表中选择日志记录。

SELECT  paymentslog.*, user.username, user.usergroupid, user.displaygroupid,
        purchase_temp.threadid
    FROM  " . TABLE_PREFIX . "paymentslog AS paymentslog
    LEFT JOIN  " . TABLE_PREFIX . "user AS user
       ON (paymentslog.userid = user.userid)
    LEFT JOIN  " . TABLE_PREFIX . "paymenttransaction AS paymenttransaction 
       ON (paymentslog.transactionid = paymenttransaction.transactionid)
    LEFT JOIN  " . TABLE_PREFIX . "paymentinfo AS paymentinfo
       ON (paymenttransaction.paymentinfoid = paymentinfo.paymentinfoid)
    LEFT JOIN  " . TABLE_PREFIX . "purchase_temp AS purchase_temp
       ON (paymentinfo.hash = purchase_temp.hash) $filterlogs_where
    GROUP BY  paymentslog.logid
    ORDER BY  paymentslog.dateline DESC
    LIMIT  $startat, $perpage 
  • 除了使用用户表连接访问用户名,usergroupid和displaygroupid
  • 之外,所有连接都需要访问SELECT上的threadid
  • 需要20秒才能运行(!),在我尝试修复它的过程中,在为事务列表(表paymentlog)添加INDEX之后,现在需要... 60秒!
  • 由于某种原因,它多次返回一个特定的行,因此我通过添加“GROUP BY paymentslog.logid”来修复它

我必须注意到:
- $ filterlogs_where PHP变量具有查询的WHERE(我通过php为paymentlog构建不同的过滤器)。 默认情况下,$ filterlogs_where的值为“1 = 1”,如果我必须应用过滤器,我会添加。=“AND paymentslog.userid = X”等等。

知道为什么这个查询太慢了吗? 我想我已经看过并编写了更复杂的查询,这些查询在几秒或几毫秒内运行。为什么这个问题与上面的查询有关?

1 个答案:

答案 0 :(得分:0)

首先,我必须告诫你不要让多个表具有相同的模式。这通常是一个糟糕的设计。

你真的需要LEFT吗?也就是说,即使'右'表没有任何内容,你想要返回一行吗?如果没有,只需使用JOIN

摆脱LEFTs可能会摆脱GROUP BY。后跟GROUP BY的联接通常会导致“增加行数”,然后是“通过分组减少”。这会在此过程中创建一个巨大的临时表,从而减慢速度。

然后我需要指出lambda存在问题 - 通常会导致冗长的查询时间。但是,我们需要摆脱GROUP BY以使这项技术成为可能。

请使用较短的别名。

现在,回到你的具体细节......好吧,首先研究上面的内容。并提供SHOW CREATE TABLE。那么这样的事情会加快速度:

SELECT ...
    FROM ( SELECT id
               ORDER BY  dateline DESC
               LIMIT  $startat, $perpage ) AS pl
    JOIN user ON ...
    JOIN ...
    ORDER BY dateline DESC;   -- yes, needs repeating