资源密集型MySQL嵌套选择

时间:2018-04-19 15:03:11

标签: mysql

我有一个非常简单的嵌套查询,在调用时要求90 +%的CPU,我似乎无法弄清楚原因。

SELECT * FROM `push_log` 
WHERE push_id IN 
(SELECT `push_id` FROM push_sent_log 
    WHERE player_id='".$player_id."' 
        OR push_group='All' 
        AND `timestamp` >= DATE_SUB(CURDATE(), INTERVAL 24 hour) ) 
    ORDER BY timestamp DESC"

所有查询字段都有索引。我有更有效的方法吗?

2 个答案:

答案 0 :(得分:2)

尝试删除子查询而不是join

SELECT p.*
      FROM push_sent_log ps
      JOIN `push_log` p ON p.push_id= ps.push_id
    WHERE ps.player_id='".$player_id."' 
        OR ps.push_group='All' 
        AND `ps.timestamp` >= DATE_SUB(CURDATE(), INTERVAL 24 hour) ) 
    ORDER BY p.timestamp DESC"

我认为你需要检查你的SQL中的where,因为它们处于同一级别似乎没有意义:

 WHERE ps.player_id='".$player_id."' 
            OR ps.push_group='All' 
            AND `ps.timestamp` >= DATE_SUB(CURDATE(), INTERVAL 24 hour)  -- why do you using OR and AND at the same time? 

答案 1 :(得分:1)

表push_sent_log的可能pushgroup,player_id和push_id不包含在任何索引中。 EXPLAIN通常需要回答这类问题。 你能发布什么从应用于嵌套SQL和完整SQL的解释中得到什么?

https://dev.mysql.com/doc/refman/5.7/en/using-explain.html

请特别注意以上页面中的以下陈述:

EXPLAIN与SELECT,DELETE,INSERT,REPLACE和UPDATE语句一起使用。

当EXPLAIN与可解释的语句一起使用时,MySQL会显示优化器中有关语句执行计划的信息。也就是说,MySQL解释了它将如何处理语句,包括有关如何连接表以及以何种顺序连接的信息。有关使用EXPLAIN获取执行计划信息的信息,请参见第8.8.2节“EXPLAIN输出格式”。

如果您认为索引未被使用时遇到问题,请运行ANALYZE TABLE以更新可能影响优化程序选择的表统计信息,例如键的基数。请参见第13.7.2.1节“ANALYZE TABLE语法”。