简体   繁体   English

使SQL查询更快

[英]Making SQL query faster

I currently have an SQL query that is taking a LONG time to load, wondered if anyone could help me? 我目前有一个需要很长时间才能加载的SQL查询,想知道是否有人可以帮助我? I'm fairly new with MySQL. 我是MySQL的新手。

This is the query: 这是查询:

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%')
)

Basically looking through some databases to find users that are not leaving notes when they access customer accounts (very naughty). 基本上,通过一些数据库来查找在访问客户帐户时没有留下笔记的用户(非常顽皮)。 There are around 30,000 records per week in the logs database, which is obviously a factor, but right now the query runs for an hour and still doesn't complete (times out, 404 error on PHP page). 日志数据库中每周大约有30,000条记录,这显然是一个因素,但是现在查询运行了一个小时,但仍未完成(超时,PHP页面上出现404错误)。

Any info needed just ask, I'd appreciate any tips or pointers. 只需问任何需要的信息,我将不胜感激任何提示或指示。

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

A composite index on (userid, date) should be sufficient to speed up both queries here. (userid, date)综合索引应足以加快此处的两个查询。 You can also try (userid, date, action) or (action, userid, date) . 您也可以尝试(userid, date, action)(action, userid, date) Depending on which column has more unique values, one index might be more effective than another. 根据哪一列具有更多唯一值,一个索引可能比另一个索引更有效。

Note that the query planner might not be able to optimize the subquery, and it will potentially execute the subquery once for each candidate row in the outer query. 请注意,查询计划程序可能无法优化子查询,并且可能会对外部查询中的每个候选行执行一次子查询。 The cost of running the inner query multiple times could be contributing to the performance problem. 多次运行内部查询的成本可能会导致性能问题。 Consider trying a join instead, and see if you get better performance: 考虑改用联接,看看是否能获得更好的性能:

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;

I've found that MySQL doesn't optimize IN and NOT IN queries very well. 我发现MySQL不能很好地优化INNOT IN查询。 Replacing them with a JOIN usually improves things. JOIN替换它们通常可以改善情况。 For NOT IN you have to use a LEFT OUTER 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

You have two "action='XXX'" in two querys(main one and the subquery) and they dont ever have any records in Common I think. 您在两个查询(主查询和子查询)中有两个“ action ='XXX'”,它们在Common中没有任何记录。 In other words, if you are looking for some applications with the action "VIEWED". 换句话说,如果您要通过“查看”操作查找某些应用程序。 You dont need to use the query: 您不需要使用查询:

SELECT applicationid FROM logs WHERE userid = '$user' AND date >= '$dateminus7' AND (action LIKE 'SUBMITTED NOTE%' OR action LIKE 'CHANGED STATUS%') 从日志中选择applicationid userid ='$ user'AND date> ='$ dateminus7'AND(类似于“已提交注释%”的操作或类似于“已更改状态%”的操作)的日志

Not sure if I missed something and whether this will help. 不知道我是否错过了什么,这是否有帮助。 I will follow this. 我会遵循的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM