MySQL distinct+sort query performance issue -
problem
the following query takes in excess of 30 seconds run unless:
- i remove sort (query <1 sec)
- i remove distinct keyword: (query <1 sec)
- start removing joins (query <5 secs)
question
how can make query run in under 1 sec. required: how can unique list of meetings related data described joins below including sort of kind.
the related data used both determining if there related field , doing group_concat operations - hence requirement have 3 different joins same bookeditems table.
thanks in advance & or suggestions! i've been banging head on 1 few hours!
query
select distinct( `meetings`.`id` ) `meeting_id`, `meetings`.`uid` meeting_uid, `meetings_serv`.`id` meetings_serv_id, `meetings_transp`.`id` meetings_transp_id, `meetings_acco`.`id` meetings_acco_id, `meetings_bookeditems`.`id` meetings_bookeditems_id `meetings` meetings left outer join `bookeditems` `meetings_serv` on `meetings`.`uid` = `meetings_serv`.`meeting_uid` , 'ser' = `meetings_serv`.`item_type` left outer join `bookeditems` `meetings_transp` on `meetings`.`uid` = `meetings_transp`.`meeting_uid` , 'tra' = `meetings_transp`.`item_type` left outer join `bookeditems` `meetings_acco` on `meetings`.`uid` = `meetings_acco`.`meeting_uid` , 'acc' = `meetings_acco`.`item_type` left outer join `bookeditems` `meetings_bookeditems` on `meetings`.`uid` = `meetings_bookeditems`.`meeting_uid` order `meetings`.`datetime` limit 0, 50
table definition
create table if not exists `bookeditems` ( `id` int(11) not null auto_increment, `meeting_uid` varchar(256) not null, `item_type` varchar(256) not null, primary key (`id`), key `meeting_uid` (`meeting_uid`(255)), key `index1` (`meeting_uid`(255),`item_type`(255)) ) engine=innodb default charset=utf8 auto_increment=5889 ; create table if not exists `meetings` ( `id` int(11) not null auto_increment, `uid` varchar(256) not null, `datetime` datetime default null, primary key (`id`), key `uid` (`uid`(255)), key `datetime` (`datetime`) ) engine=innodb default charset=utf8 auto_increment=7487 ;
result of explain select
id | select_type | table | type | possible_keys | key | key_len | ref | rows | ------------------------------------------------------------------------------------------------------------------------------------- 1 | simple | meetings | | null | null | null | null | 7483 | using temporary; using filesort 1 | simple | meetings_serv | ref | meeting_uid,index1 | meeting_uid | 767 | test.meetings.uid | 1 | 1 | simple | meetings_transp | ref | meeting_uid,index1 | meeting_uid | 767 | test.meetings.uid | 1 | 1 | simple | meetings_acco | ref | meeting_uid,index1 | meeting_uid | 767 | test.meetings.uid | 1 | 1 | simple | meetings_bookeditems | ref | meeting_uid,index1 | meeting_uid | 767 | test.meetings.uid | 1 |
result of profiling
starting 0.000092 checking permissions 0.000003 checking permissions 0.000002 checking permissions 0.000001 checking permissions 0.000001 checking permissions 0.000003 opening tables 0.000036 system lock 0.000008 init 0.000033 optimizing 0.000005 statistics 0.000035 preparing 0.000019 creating tmp table 0.000165 executing 0.000004 copying tmp table 1.790968 converting heap myisam 1.669041 copying tmp table on disk 28.32606 sorting result 0.141737 sending data 0.000099 end 0.000005 removing tmp table 0.022097 end 0.000014 query end 0.000008 closing tables 0.000017 freeing items 0.000779 logging slow query 0.000004 cleaning 0.000005
part solution
based on eric r. rath's below have profiled query , adding max_heap_table_size=256m & tmp_table_size=256m mysql config have been able eliminate execution steps "converting heap myisam" , "copying tmp table on disk".
although beings total execution time down under 2 seconds, still not convinced can if there other suggestions in terms of query optimisation please let me know.
profiling following max_heap_table_size & tmp_table_size config
... executing 0.000004 copying tmp table 1.790968 sorting result 0.141737 ...
i think index2 unnecessary , can removed; it's prefix of index1. won't decrease query time, though.
the explain output shows real culprit: "using temporary, using filesort". can avoid having mysql perform ordering same key used join. if change index1 (meeting_id, datetime), might able so. if need keep item_type in index1, either add third column in index, or include in() clause in query values.
Comments
Post a Comment