MySQL查询Pegs服务器100% - 有时

时间:2011-09-28 15:13:33

标签: php mysql

我的MySQL查询运行非常非常缓慢,并且一旦执行就将服务器使用率固定为100%....有时候。

以下是查询:

SELECT DISTINCT r1.recordID, 
       (SELECT MAX(r2.date) 
            FROM reminders as r2 
            WHERE r2.owner = '$owner' 
                AND r2.recordID = r1.recordID 
                AND r2.status = 'Active' 
                AND r2.followUp != 'true' 
            ORDER BY r2.date DESC LIMIT 1) as maxDate 
    FROM reminders as r1 
    WHERE r1.owner = '$owner' 
        AND (SELECT MAX(r2.date) 
                 FROM reminders as r2 
                 WHERE r2.recordID = r1.recordID 
                     AND r2.status = 'Active' 
                     AND r2.followUp != 'true' 
                 ORDER BY r2.date DESC LIMIT 1) <= '$date' 
        AND (SELECT do_not_call 
                 FROM marketingDatabase 
                 WHERE id = r1.recordID) != 'true' 
        AND r1.status = 'Active' 
    ORDER BY maxDate DESC

我不确定这是一个写得不好的查询(可能是......我是新手)或其他什么。有时它工作正常,结果几乎立即返回,但有时需要很长时间(15+分钟)和100%服务器资源才能返回结果。

知道为什么会这样吗?我可以对查询做些什么来防止这种情况?

提前致谢!

[编辑]

这是EXPLAIN。

Array
(
    [0] => Array
        (
            [id] => 1
            [select_type] => PRIMARY
            [table] => r1
            [type] => ALL
            [possible_keys] => 
            [key] => 
            [key_len] => 
            [ref] => 
            [rows] => 2073
            [Extra] => Using where; Using temporary; Using filesort
        )

    [1] => Array
        (
            [id] => 4
            [select_type] => DEPENDENT SUBQUERY
            [table] => marketingDatabase
            [type] => eq_ref
            [possible_keys] => PRIMARY
            [key] => PRIMARY
            [key_len] => 4
            [ref] => teleforce.r1.recordID
            [rows] => 1
            [Extra] => 
        )

    [2] => Array
        (
            [id] => 3
            [select_type] => DEPENDENT SUBQUERY
            [table] => r2
            [type] => ALL
            [possible_keys] => 
            [key] => 
            [key_len] => 
            [ref] => 
            [rows] => 2073
            [Extra] => Using where
        )

    [3] => Array
        (
            [id] => 2
            [select_type] => DEPENDENT SUBQUERY
            [table] => r2
            [type] => ALL
            [possible_keys] => 
            [key] => 
            [key_len] => 
            [ref] => 
            [rows] => 2073
            [Extra] => Using where
        )
)

2 个答案:

答案 0 :(得分:1)

有些事情可能会导致此查询变慢。

一:一般来说,首先要检查的是索引。您必须为r1中的每个记录执行三个嵌入式查询。如果其中任何一个无法有效使用索引并且必须处理大量记录,则此查询将非常慢。检查索引,并使用“explain”查看正在使用的内容。

二:嵌入式查询往往比连接慢。看看你是否无法将一些嵌入式查询转换为连接。

三:在这个特定的查询中,你可以自己加入“余数”,据我所知,只是找到最大值(日期)。为什么不使用GROUP BY?我改进此查询的第1步是:

select r1.recordID, max(r1.date) as maxdate
from reminders as r1
where r1.owner=$owner and r1.status='Active' and r1.followUp!='true'
and (SELECT do_not_call FROM marketingDatabase WHERE id = r1.recordID) != 'true'
group by r1.recordID
having max(r1.date)<=$date
order by maxdate desc

我没有你的数据库来测试这个,但我认为它会给出相同的结果。

四:我将其他嵌入式查询转换为连接。像:

select r1.recordID, max(r1.date) as maxdate
from reminders as r1
join marketingDatabase as m on m.id=r1.recordID
where r1.owner=$owner and r1.status='Active' and r1.followUp!='true'
and m.do_not_call != 'true'
group by r1.recordID, r1.owner
having max(r1.date)<=$date
order by maxdate desc

(我不确定记录ID是什么标识的。从您的查询中可以看出,您可以在具有相同记录标识的提醒中拥有多条记录。)

五:如果你有提醒索引(所有者,日期)和marketingDatabase(id),你可能会获得最佳性能。

六:顺便说一句,如果“do_not_call”和followUp是真/假,它们应该是布尔值而不是变量。你只是浪费磁盘空间和执行时间处理“true”而不是布尔值TRUE。而你创造了错误拼写的问题,比如“ture”或“True”。在绝对最差的情况下,将它们设为char(1),T或F.

有时您需要嵌入式查询,但它们应该是最后的选择。

答案 1 :(得分:0)

尝试使用命令

reminders.owner上创建索引
CREATE INDEX someNameYouChoose ON reminders(owner);