Mysql 使用where子句或在where子句中执行慢速查询

Mysql 使用where子句或在where子句中执行慢速查询,mysql,Mysql,请告知如何改进此慢速查询 SELECT response.`reasonid` FROM response INNER JOIN ACTION ON action.actionid = response.actionid WHERE response.respdate BETWEEN 20160305 AND 20160905 AND ( ( response.reasonid = 'Prospect Call

请告知如何改进此慢速查询

SELECT response.`reasonid`
FROM response 
    INNER JOIN ACTION ON action.actionid = response.actionid 
WHERE 
    response.respdate BETWEEN 20160305 
    AND 20160905 
    AND 
    (
        (
         response.reasonid = 'Prospect Call' 
         AND response.typeid = '0'
         AND action.typeid = '9'
        ) 
    OR 
        (
         response.typeid = '1000'  
         AND action.typeid = '1'
        )
    ) 
有以下索引:

response.actionid/response.reasonid/response.typeid/action.typeid/response.respdate

解释结果:

 table   type   possible_keys                   key           key_len  ref               rows   Extra

ACTION   range  PRIMARY,idx_actiontypeid    idx_actiontypeid    5      \N               310617  Using where; Using index
response ref    idx_respdate2,idx_actionid, idx_actionid        5      ACTION.actionid    1         Using where
            idx_reasonid,idx_resptypeid

尝试此查询将一些索引列添加到联接中

SELECT response.`reasonid`
FROM response 
    INNER JOIN ACTION ON action.actionid = response.actionid   and response.typeid in( '1000','0') and action.typeid in('0','1')
WHERE 
    response.respdate BETWEEN 20160305 
    AND 20160905 
    AND 
    (
        (
         response.reasonid = 'Prospect Call' 
         AND response.typeid = '0'
         AND action.typeid = '9'
        ) 
    OR 
        (
         response.typeid = '1000'  
         AND action.typeid = '1'
        )
    )
试试看: 将表的大小减小到只需要使用的大小:

select a.* 
from (
      SELECT response.`reasonid`
      FROM response 
      WHERE response.respdate BETWEEN 20160305 AND 20160905 
      ) a
INNER JOIN ACTION ON action.actionid = a.actionid
WHERE (
     response.reasonid = 'Prospect Call' 
     AND response.typeid = '0'
     AND action.typeid = '9'
    ) 
OR 
    (
     response.typeid = '1000'  
     AND action.typeid = '1'
    )

请尝试在数据库中指定查询中的日期:

SELECT response.`reasonid`
FROM response 
    INNER JOIN ACTION ON action.actionid = response.actionid 
WHERE 
    response.respdate BETWEEN "2016-03-05" 
    AND "2016-09-05" 
    AND 
    (
        (
         response.reasonid = 'Prospect Call' 
         AND response.typeid = '0'
         AND action.typeid = '9'
        ) 
    OR 
        (
         response.typeid = '1000'  
         AND action.typeid = '1'
        )
    ) 
并检查这是否加快了查询速度。
如果以数值形式写入(20160305),则数据库在比较前必须对每一行执行隐式类型转换,这可能会导致性能降低。

您的查询上不应该有单独的索引,而应该有一个复合索引甚至覆盖索引。我很惊讶没有其他人对此发表评论。我为索引提供以下建议

表索引 响应(类型ID、响应日期、推理、操作ID) 动作(动作ID,类型ID)

然后我调整了查询以使用UNION而不是OR

select distinct
      r.reasonid
   from
      response r join action a
         on r.actionid = a.actionid
         AND a.typeid = 9
   where
          r.typeid = 0
      and r.respdate between 20160305 and 20160905
      and r.reasonid = 'Prospect Call'
union
select 
      r.reasonid
   from
      response r join action a
         on r.actionid = a.actionid
         AND a.typeid = 1
   where
          r.typeid = 1000
      and r.respdate between 20160305 and 20160905

请对此查询执行explain TANKS Manesh-但查询时间不变。添加了上面的解释。respdate是什么数据类型?是日期、日期时间还是整数?你说的“慢”是什么意思?1秒?1分钟?respdate是一个日期字段。慢是6秒。谢谢,但仍然很慢。但这是一种改进吗?不要这样认为-因为缓存查询每次都会运行得更快;)也许值得尝试通过在派生表中添加另一个where子句来进一步缩小范围,例如:20160305和20160905之间的where response.respdate和(01000)日期更改中的response.typeID没有帮助,但TQI,great idea肯定更快。