Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何优化SQL查询?钥匙没有被使用_Mysql_Sql_Performance_Optimization - Fatal编程技术网

Mysql 如何优化SQL查询?钥匙没有被使用

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

如何优化以下查询?我曾尝试创建索引(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(), 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