2016-07-05 41 views
2

请告知如何改善这种缓慢的查询。缓慢查询与OR在哪里条款

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 
+0

什么数据类型是respdate?它是一个日期,日期时间,整数? “慢”是什么意思? 1秒? 1分钟? – Olli

+0

respdate是一个日期字段。慢6秒。 – zima10101

回答

0

你的查询不应该有它的单独索引,但一个复合或甚至覆盖索引。我很惊讶没有人评论过。我为指标

表索引 响应(typeid的,respdate,合理,actionid) 行动(actionid,typeid的)

后来我调整了查询​​使用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 
+0

嗨,好主意明显更快。 – zima10101

0

试此查询添加了一些索引列加入

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' 
     ) 
    ) 
+0

请执行解释此查询 –

+0

谢谢Manesh - 但没有改变查询时间。上面已经添加了解释。 – zima10101

0

试一下: 减少表下来的大小,只需要使用什么:

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' 
    ) 
+0

谢谢,但仍然很慢 – zima10101

+0

但它是一个改进? – kostas

+0

不这么认为 - 由于缓存查询运行速度比较快;) – zima10101

0

请尽量在查询中指定的日期,因为它们是在数据库:

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),则数据库在比较每行时必须对每行执行隐式类型转换,这可能会导致性能下降。

+0

更改日期没有帮助,但TQ – zima10101