0

我目前有一个 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 错误)。

任何需要的信息都可以询问,我将不胜感激任何提示或指示。

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

4

3 回答 3

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;
于 2013-04-29T15:35:52.783 回答
0

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

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

不确定我是否错过了什么以及这是否会有所帮助。我会遵循这个。

于 2013-04-29T15:41:22.193 回答
0

我发现 MySQL 并没有很好地优化INNOT IN查询。用 a 替换它们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
于 2013-04-29T15:37:34.147 回答