我的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
)
)
答案 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);