我目前有一个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
答案 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没有很好地优化IN
和NOT 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(行动就像'提交注意'或行动像'改变状态%')
不确定我是否错过了某些内容以及这是否会有所帮助。我会遵循这个。