I have a query that is taking 33 Sec’s is there any better way to rewrite it,How can i transform it to the Procedure
select ut.templateId,
(
case
when ut.reportTypeId=4 then 'Account'
when ut.reportTypeId=5 then 'Campaign'
when ut.reportTypeId=6 then 'AdGroup'
when ut.reportTypeId=7 then 'Ad'
when ut.reportTypeId=8 then 'Keyword'
end
)as ReportType ,
ur.reportId,
(case when timestampdiff(SECOND,b.createdTS,a.createdTS) < 5 then a.reportId else 0 end) as '<5secs',
(case when timestampdiff(SECOND,b.createdTS,a.createdTS) between 5 and 10 then a.reportId else 0 end) as '5-10secs',
(case when timestampdiff(SECOND,b.createdTS,a.createdTS) between 11 and 20 then a.reportId else 0 end) as '11-20secs',
(case when timestampdiff(SECOND,b.createdTS,a.createdTS) between 21 and 30 then a.reportId else 0 end) as '21-30secs',
(case when timestampdiff(SECOND,b.createdTS,a.createdTS) between 31 and 60 then a.reportId else 0 end) as '31-60secs',
(case when timestampdiff(SECOND,b.createdTS,a.createdTS) between 61 and 120 then a.reportId else 0 end) as '61-120secs',
(case when timestampdiff(SECOND,b.createdTS,a.createdTS) between 121 and 1800 then a.reportId else 0 end) as '2-30mins',
(case when timestampdiff(SECOND,b.createdTS,a.createdTS) > 1800 then a.reportId else 0 end) as '>30mins'
from
(select reportId,createdTS from T_ReportMonitor where status='EndSP')a,
(select reportId,createdTS from T_ReportMonitor where status='BeginSP')b,
(select templateId,reportTypeId,reportConsoleType from T_UserTemplate) ut,
(select reportId,templateId,createdTS,modifiedTS,isDeleted from T_UserReport) ur
where a.reportId=b.reportId
and date(ur.createdTS) = 20120731
and ut.templateId=ur.templateId
and reportConsoleType in ('Adser','APIAdser')
and ur.isDeleted=false
and a.reportId=ur.reportId
and ur.reportId!=313509 AND ur.reportId!=313510 AND ur.reportId!=313511 AND ur.reportId!=313512 AND ur.reportId!=313509 AND ur.reportId!=313510 AND ur.reportId!=313511 AND ur.reportId!=313512 AND ur.reportId!=313520;
The Explain Result of the Query is as
+----+-------------+-----------------+------+---------------+------+---------+------+--------+--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------+------+---------------+------+---------+------+--------+--------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 20071 | |
| 1 | PRIMARY | <derived3> | ALL | NULL | NULL | NULL | NULL | 20072 | Using where; Using join buffer |
| 1 | PRIMARY | <derived5> | ALL | NULL | NULL | NULL | NULL | 148591 | Using where; Using join buffer |
| 1 | PRIMARY | <derived4> | ALL | NULL | NULL | NULL | NULL | 154030 | Using where; Using join buffer |
| 5 | DERIVED | T_UserReport | ALL | NULL | NULL | NULL | NULL | 124008 | |
| 4 | DERIVED | T_UserTemplate | ALL | NULL | NULL | NULL | NULL | 151745 | |
| 3 | DERIVED | T_ReportMonitor | ALL | NULL | NULL | NULL | NULL | 60849 | Using where |
| 2 | DERIVED | T_ReportMonitor | ALL | NULL | NULL | NULL | NULL | 60849 | Using where |
+----+-------------+-----------------+------+---------------+------+---------+------+--------+--------------------------------+
I have the Keys on the Columns that are used in the where clause and any other comparison but none of them is being used in query, is it due the reason that they are derived query.
The main problem with your query is it uses subqueries. MySQL can’t use an index on a subquery since it basically creates a new table in memory (or on disk) for your subquery. Try to make joins instead.
Try this one
Make sure there is a key on T_ReportMonitor.reportId, T_ReportMonitor.status and T_UserReport.reportId.
There is one more thing that will degrade your query. Your using a function in the where:
This means that MySQL will have to process each row to see what the outcome of this function will be. This might even prove to be the largest performance increase. Try to either make that field a date field (or create a new date field) or use something like