我使用的是mysql服务器,在该服务器中,我使用以下设置设置了慢查询日志
log-slow-queries=/var/log/mysql/mysql-slow-queries.log
long_query_time=1
log-queries-not-using-indexes我已经在mysql事件中为每分钟设置了以下事件。
UPDATE mytable SET playing = 0
WHERE playing != 0
AND ( TIMESTAMPDIFF( MINUTE , lastplayed, NOW( )) >10 )
OR ( lastplayed IS NULL
AND ispresent= 0
);现在,所有这些列playing, lastplayed, and ispresent都已被索引,但这仍然出现在慢查询日志中,并具有以下详细信息
# Query_time: 0.000585 Lock_time: 0.000159 Rows_sent: 0 Rows_examined: 316为什么这个查询显示在慢速日志中?
发布于 2015-12-23 19:35:58
我的猜测是,当您在函数(在本例中为TIMESTAMPDIFF)中使用lastplayed时,不能使用索引。MySQL不够聪明,无法理解您正在寻找的是all lastplayed stamps which are older than 10 minutes。因此,它遍历所有行。
相反,您可以使用以下命令:
... AND lastplayed < DATE_SUB(NOW(), INTERVAL 10 MINUTE) ...然后,MySQL只计算一次DATE_SUB,然后就可以将lastplayed与实际的整数值进行比较。通过这种方式,MySQL再次变得足够智能,可以使用索引。
详细原因:
假设您编写了自己的MySQL函数(伪代码):
function weirdFunction(Integer i): {
if (RAND() < 0.5) return i;
else return 0;
}现在,当您想要运行查询时,如下所示:
... AND weirdFunction(lastplayed) = 0 ...MySQL如何知道哪些最后播放的值将给出哪些结果?它不能。它需要对所有行执行函数才能找出答案。因此不能使用任何索引。
发布于 2015-12-24 10:55:19
通过执行两个UPDATEs来删除OR,OR的两端各一个
UPDATE mytable SET playing = 0
WHERE lastplayed < NOW() - INTERVAL 10 MINUTE;
UPDATE mytable SET playing = 0
WHERE lastplayed IS NULL
AND ispresent= 0; (前提是您拥有优先级权限。)
它们将需要并使用这个“综合”索引:
INDEX(lastplayed, ispresent)(每列上的单独索引效率不高。)
https://stackoverflow.com/questions/34434730
复制相似问题