Mysql 如何优化SQL查询?钥匙没有被使用
如何优化以下查询?我曾尝试创建索引(idx_事件,idx_事件,idx_开始日期),但没有帮助。查询需要10秒,这太多了Mysql 如何优化SQL查询?钥匙没有被使用,mysql,sql,performance,optimization,Mysql,Sql,Performance,Optimization,如何优化以下查询?我曾尝试创建索引(idx_事件,idx_事件,idx_开始日期),但没有帮助。查询需要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(), ev
....
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)
。。。。
一组131行(10.25秒)
mysql>解释从结果中选择results.event
结果上的内部联接事件。事件=事件.id
其中(DATEDIFF(NOW(),events.startdate)<30)
和(DATEDIFF(NOW(),events.startdate)>-1)
和结果。状态='OK'
按events.id分组;
+----+-------------+---------+--------+----------------------------------------------+------------+---------+-----------------------+--------+---------------------------------------------------------------------+
|id |选择|类型|类型|可能的|键|键|列|参考|行|额外|
+----+-------------+---------+--------+----------------------------------------------+------------+---------+-----------------------+--------+---------------------------------------------------------------------+
|1 |简单|结果|参考| idx | U事件| idx | U状态| 53 |常数| 773425 |使用索引条件;使用where;使用临时;使用文件排序|
|1 |简单|事件| eq|u ref |主要,idx|u事件|名称,idx|u事件|开始日期|主要| 4 | eventor.results.event | 1 |使用where|
+----+-------------+---------+--------+----------------------------------------------+------------+---------+-----------------------+--------+---------------------------------------------------------------------+
一组2行(0.01秒)
将索引列包装到函数中会阻止优化程序使用它。看起来您需要在startdate释放索引,以便为您的联接获得良好的筛选结果集:
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'
从结果中选择r.event
参加活动e
关于e.id=r.event
和e.startdate>CURDATE()-间隔30天
和e.startdate
我喜欢将联接表条件放在ON子句中,并尽可能使用表别名
我更喜欢整数状态列而不是字符串“OK”,如果需要,可以将其外键到状态表中,并附上描述
另外,我还喜欢使用
=
和在函数中包装索引列,以防止优化程序使用它。看起来您需要在startdate释放索引,以便为您的加入获得一个良好的筛选结果集:
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'
从结果中选择r.event
参加活动e
关于e.id=r.event
和e.startdate>CURDATE()-间隔30天
和e.startdate
我喜欢将联接表条件放在ON子句中,并尽可能使用表别名
我更喜欢整数状态列而不是字符串“OK”,如果需要,可以将其外键到状态表中,并附上描述
另外,我还喜欢使用=
和而不是datediff
,将日期与预先计算的值进行比较(传递到查询)首先在events.startdate上旋转这两个条件。将列放在一边,将常量放在另一边。这样引擎应该理解它可以使用索引。对于datediff
执行其工作,构造查询的方式使它读取表中所有可能的记录以计算值。因此e、 @TJ所说的-预先计算日期值。不要试图“智能地”编写查询,然后在表中抛出索引,希望它能加快速度。@TJ我宁愿在这样的查询中计算日期,也不愿将其传入。@Arth Me。CURDATE()-当时我没有想到INTERVAL 30
。我建议使用一种方法来避免导致忽略索引的差异。与其使用datediff
,不如将日期与预先计算的值进行比较(传递到查询)首先在events.startdate上旋转这两个条件。将列放在一边,将常量放在另一边。这样引擎应该理解它可以使用索引。对于datediff
执行其工作,构造查询的方式使它读取表中所有可能的记录以计算值。因此e、 @TJ所说的-预先计算日期值。不要试图“智能地”编写查询,然后在表中抛出索引,希望它能加快速度。@TJ我宁愿在这样的查询中计算日期,也不愿将其传入。@Arth Me。CURDATE()-当时我没有想到INTERVAL 30
。我正在建议一种方法来避免导致忽略索引的差异。我在执行查询时遇到一个错误:错误1064(42000):您的SQL语法有错误;请查看与您的MySQL服务器版本对应的手册,以了解在第1行hanks!132行(0.61秒)处使用的接近'DAYS和e.startdate