使SQL查询更快

时间:2013-04-29 15:30:06

标签: mysql query-optimization

我目前有一个SQL查询需要花费很长时间才能加载,想知道是否有人可以帮助我?我对MySQL很新。

这是查询:

SELECT applicationid 
FROM logs 
WHERE action = 'VIEWED' 
AND userid = '$user' 
AND date >= '$dateminus7' 
AND applicationid NOT IN (
     SELECT applicationid 
     FROM logs 
     WHERE userid = '$user' 
     AND date >= '$dateminus7' 
     AND (action LIKE 'SUBMITTED NOTE%' OR action LIKE 'CHANGED STATUS%')
)

基本上查看一些数据库,以查找在访问客户帐户时非离开笔记的用户(非常顽皮)。日志数据库中每周大约有30,000条记录,这显然是一个因素,但是现在查询运行了一个小时仍然没有完成(超时,PHP页面上有404错误)。

任何需要的信息只是问,我会感谢任何提示或指示。

编辑:EXPLAIN结果http://i.imgur.com/h9bZBe3.png

3 个答案:

答案 0 :(得分:1)

(userid, date)上的复合索引应该足以加速这两个查询。您也可以尝试(userid, date, action)(action, userid, date)。根据哪个列具有更多唯一值,一个索引可能比另一个索引更有效。

请注意,查询计划程序可能无法优化子查询,并且可能会为外部查询中的每个候选行执行一次子查询。多次运行内部查询的成本可能会导致性能问题。考虑尝试加入,看看你是否获得了更好的表现:

SELECT la.applicationid 
FROM logs la

LEFT OUTER JOIN logs lb
    ON la.applicationid = lb.applicationid
    AND lb.userid = '$user' 
    AND lb.date >= '$dateminus7' 
    AND (lb.action LIKE 'SUBMITTED NOTE%' OR lb.action LIKE 'CHANGED STATUS%')

WHERE la.action = 'VIEWED' 
AND la.userid = '$user' 
AND la.date >= '$dateminus7' 
AND lb.applicationid IS NULL;

答案 1 :(得分:0)

我发现MySQL没有很好地优化INNOT IN查询。用JOIN替换它们通常会改善一些事情。对于NOT IN,您必须使用LEFT OUTER JOIN

SELECT l1.applicationid
FROM logs l1
LEFT OUTER JOIN (SELECT applicationid 
     FROM logs 
     WHERE userid = '$user' 
     AND date >= '$dateminus7' 
     AND (action LIKE 'SUBMITTED NOTE%' OR action LIKE 'CHANGED STATUS%')) l2
ON l1.applicationid = l2.applicationid
WHERE l1.action = 'VIEWED' 
AND l1.userid = '$user' 
AND l1.date >= '$dateminus7'
AND l2.applicationid IS NULL

答案 2 :(得分:0)

你在两个查询中有两个“action ='XXX'”(主要的一个和子查询),他们没有任何常见的记录我认为。 换句话说,如果您正在寻找具有“VIEWED”操作的某些应用程序。您不需要使用查询:

SELECT applicationid      从日志      WHERE userid ='$ user'      AND date> ='$ dateminus7'      AND(行动就像'提交注意'或行动像'改变状态%')

不确定我是否错过了某些内容以及这是否会有所帮助。我会遵循这个。