Please advise how to improve this slow query.
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'
)
)
There are indexes on:
response.actionid / response.reasonid / response.typeid / action.typeid / response.respdate
Explain results:
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
try this query added some index columns into join
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'
)
)
Try that: Reduce the size of the table down to only what you need to use:
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'
)
Please try to specify the dates in your query as they are in the database:
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'
)
)
and check if this speeds up your query. If you write it as numeric value (20160305), the database has to do an implicit typecast on every line before comparing it, which might lead to slower performance.
Your query should not have individual indexes on it, but a composite or even covering indexes. Which I am surprised nobody else commented on. I offer the following suggestion for indexes
table index response ( typeid, respdate, reasoned, actionid ) action ( actionid, typeid )
Then I adjusted the query to use a UNION instead of an 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.