MySQL复合索引对连接的影响
我有以下SQL查询(DB是MySQL 5): “显示创建表MySQL复合索引对连接的影响,mysql,sql,indexing,Mysql,Sql,Indexing,我有以下SQL查询(DB是MySQL 5): “显示创建表事件参与者”: 此外,查询本身看起来很难看,但这是生产系统上的遗留代码,因此我们不希望更改它(至少目前是这样) 问题是,事件表(在生产系统中)上大约有3600万条记录,因此由于使用临时数据库,数据库机器频繁崩溃;使用filesort处理(他们提供了这些解释输出,不幸的是,我现在没有这些输出。我稍后会尝试将它们更新到本文。) 客户通过添加索引要求“快速修复”。目前我们在偶数t和事件参与者上分别有完整会话id、pat\u id、日期(单独)和
事件参与者”:
此外,查询本身看起来很难看,但这是生产系统上的遗留代码,因此我们不希望更改它(至少目前是这样)
问题是,事件
表(在生产系统中)上大约有3600万条记录,因此由于使用临时数据库,数据库机器频繁崩溃;使用filesort
处理(他们提供了这些解释输出,不幸的是,我现在没有这些输出。我稍后会尝试将它们更新到本文。)
客户通过添加索引要求“快速修复”。目前我们在偶数
t和事件参与者
上分别有完整会话id、pat\u id、日期
(单独)和用户id
的索引。
因此,我正在考虑在事件上创建一个复合索引(pat\u id,exe\u id,full\u session\u id,date)
-该索引包括联接中的字段(相当于where?),然后分组,然后聚合(min)部分。
这只是一个想法,因为我们目前没有这种数据量可供测试,所以我们先尽最大努力
我的问题是:
- 上述指标是否有助于提高绩效?(效果相当混乱,因为我发现了两个截然不同的结果:
与之相比,后者表示连接上的复合索引不起作用,前者表示它起作用
- 这条路径(添加索引)有希望吗?还是我们应该忘记它,转而尝试优化查询
提前感谢您的帮助:)
更新:
我已经更新了两个相关表的完整表说明
MySQL版本是5.1.69。但我认为我们不需要担心评论中提到的含糊不清的数据问题,因为我们的数据似乎不会含糊不清。具体来说,对于每个完整的会话id,只返回一个“event_exe.user_id”(它只是应用程序中的一个业务逻辑)
那么,您对我的两个问题有何看法?认为分组依据
无效,这将对较新的MySQL版本产生错误(除非处于兼容模式)。您通常会按照所选的相同列进行分组,但设置函数的参数除外。也就是说,尝试按事件分组。完整会话id,事件执行。用户id
。是否为事件。完整会话id
在您的表中唯一?这意味着它有主键还是唯一键?如果您的查询无效,请参见@jarlh别忘了MySQL支持SQL:1999标准中的可选功能,该功能允许在按列分组的情况下使用此类非聚集。我还建议您对查询问题中涉及的每个表使用SHOW CREATE TABLE TABLE
,并将其发布在此处,以便我们了解数据类型和定义的索引比。。代码说明得更多,更清晰,然后用文本解释。@RaymondNijland,但我想不是MySQL版本5吧?无论如何,我还是建议使用旧的规则,因为它永远不会出错。groupby
是无效的,对于较新的MySQL版本会出现错误(除非处于兼容模式)。您通常会将所选的列分组,除了那些作为设置函数参数的列。也就是说,尝试按事件分组。完整会话id,事件执行。用户id
。是否为事件。完整会话id
在您的表中唯一?这意味着它有主键还是唯一键?如果您的查询无效,请参见@jarlh别忘了MySQL支持SQL:1999标准中的可选功能,该功能允许在按列分组的情况下使用此类非聚集。我还建议您对查询问题中涉及的每个表使用SHOW CREATE TABLE TABLE
,并将其发布在此处,以便我们了解数据类型和定义的索引比。。代码说明得更多,更清晰,然后用文本解释。@RaymondNijland,但我想不是MySQL版本5吧?无论如何,我还是推荐旧规则,因为它永远不会出错。
select
event.full_session_id,
DATE(min(event.date)),
event_exe.user_id,
COUNT(DISTINCT event_pat.user_id)
FROM
event AS event
JOIN event_participant AS event_pat ON
event.pat_id = event_pat.id
JOIN event_participant AS event_exe on
event.exe_id = event_exe.id
WHERE
event_pat.user_id <> event_exe.user_id
GROUP BY
event.full_session_id;
CREATE TABLE `event` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`date` datetime NOT NULL,
`session_id` varchar(64) DEFAULT NULL,
`full_session_id` varchar(72) DEFAULT NULL,
`pat_id` int(12) DEFAULT NULL,
`exe_id` int(12) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `SESSION_IDX` (`full_session_id`),
KEY `PAT_ID_IDX` (`pat_id`),
KEY `DATE_IDX` (`date`),
KEY `SESSLOGPATEXEC_IDX` (`full_session_id`,`date`,`pat_id`,`exe_id`)
) ENGINE=MyISAM AUTO_INCREMENT=371955 DEFAULT CHARSET=utf8
CREATE TABLE `event_participant` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`user_id` varchar(64) NOT NULL,
`alt_user_id` varchar(64) NOT NULL,
`username` varchar(128) NOT NULL,
`usertype` varchar(32) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ALL_UNQ` (`user_id`,`alt_user_id`,`username`,`usertype`),
KEY `USER_ID_IDX` (`user_id`)
) ENGINE=MyISAM AUTO_INCREMENT=5397 DEFAULT CHARSET=utf8