问题
以下查询需要超过 30 秒才能运行,除非:
- 我删除排序(查询然后<1秒)
- 我删除了 distinct 关键字:(查询然后 <1 秒)
- 开始删除连接(查询然后 <5 秒)
问题
我怎样才能让这个查询在 1 秒内运行。必需:如何获得具有相关数据的唯一会议列表,如下面的连接所述,包括某种类型。
相关数据既用于确定是否存在相关字段,也用于执行 GROUP_CONCAT 操作 - 因此需要对同一个预定项目表进行 3 个不同的连接。
提前感谢您的任何帮助和建议!我已经在这个问题上敲了几个小时!
询问
SELECT
DISTINCT( `meetings`.`id` ) AS `meeting_id`,
`meetings`.`uid` AS meeting_uid,
`meetings_SERV`.`id` AS meetings_SERV_id,
`meetings_TRANSP`.`id` AS meetings_TRANSP_id,
`meetings_ACCO`.`id` AS meetings_ACCO_id,
`meetings_BOOKEDITEMS`.`id` AS meetings_BOOKEDITEMS_id
FROM `meetings` AS meetings
LEFT OUTER JOIN `bookeditems` AS `meetings_SERV`
ON `meetings`.`uid` = `meetings_SERV`.`meeting_uid`
AND 'SER' = `meetings_SERV`.`item_type`
LEFT OUTER JOIN `bookeditems` AS `meetings_TRANSP`
ON `meetings`.`uid` = `meetings_TRANSP`.`meeting_uid`
AND 'TRA' = `meetings_TRANSP`.`item_type`
LEFT OUTER JOIN `bookeditems` AS `meetings_ACCO`
ON `meetings`.`uid` = `meetings_ACCO`.`meeting_uid`
AND 'ACC' = `meetings_ACCO`.`item_type`
LEFT OUTER JOIN `bookeditems` AS `meetings_BOOKEDITEMS`
ON `meetings`.`uid` = `meetings_BOOKEDITEMS`.`meeting_uid`
ORDER BY `meetings`.`datetime`
LIMIT 0, 50
表定义
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 ;
解释选择的结果
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
-------------------------------------------------------------------------------------------------------------------------------------
1 | SIMPLE | meetings | ALL | 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 |
分析结果
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 to tmp table 1.790968
converting HEAP to MyISAM 1.669041
Copying to 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 up 0.000005
零件解决方案
根据下面 Eric R. Rath 的帮助,我已经分析了查询,并通过将 max_heap_table_size=256M 和 tmp_table_size=256M 添加到 MySQL 配置中,我已经能够消除执行步骤“将 HEAP 转换为 MyISAM”和“复制到磁盘上的 tmp 表” ”。
尽管这将总执行时间降至 2 秒以下,但我仍然不相信这是我能做的一切,如果在查询优化方面有任何其他建议,请告诉我。
按照 max_heap_table_size 和 tmp_table_size 配置进行分析
...
executing 0.000004
Copying to tmp table 1.790968
Sorting result 0.141737
...