Mar*_*son 0 mysql sql optimization performance
如何优化以下查询?我试图创建索引(idx_events,idx_events_startdate,但它们没有帮助.查询需要10秒,这太过分了.
....
131 rows in set (10.25 sec)
mysql> explain SELECT results.event from results
INNER JOIN events ON results.event=events.id
where (DATEDIFF(NOW(), events.startdate) < 30)
AND (DATEDIFF(NOW(), events.startdate) > -1)
AND results.status='OK'
group by events.id;
+----+-------------+---------+--------+----------------------------------------------+------------+---------+-----------------------+--------+---------------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+--------+----------------------------------------------+------------+---------+-----------------------+--------+---------------------------------------------------------------------+
| 1 | SIMPLE | results | ref | idx_event,idx_status | idx_status | 53 | const | 773425 | Using index condition; Using where; Using temporary; Using filesort |
| 1 | SIMPLE | events | eq_ref | PRIMARY,idx_events_name,idx_events_startdate | PRIMARY | 4 | eventor.results.event | 1 | Using where |
+----+-------------+---------+--------+----------------------------------------------+------------+---------+-----------------------+--------+---------------------------------------------------------------------+
2 rows in set (0.01 sec)
Run Code Online (Sandbox Code Playgroud)
在函数中包装索引列会阻止优化程序使用它.看起来你需要释放startdate上的索引来为你的JOIN获得一个很好的过滤结果集:
SELECT r.event from results
JOIN events e
ON e.id = r.event
AND e.startdate > CURDATE() - INTERVAL 30 DAY
AND e.startdate < CURDATE() + INTERVAL 1 DAY
WHERE r.status = 'OK'
Run Code Online (Sandbox Code Playgroud)
我喜欢将我的连接表条件放在ON子句中,并尽可能使用表别名.
我也更喜欢整数状态列到字符串'OK',如果需要,可以将其外键到具有描述的状态表.
作为一个补充说明..我也喜欢使用>=和<日期范围,例如,如果startdate是DATETIME或TIMESTAMP,此查询将排除值,2014-08-01 00:00:00如果它是在切断CURDATE() - INTERVAL 30 DAY.