我有以下SQL查询(数据库为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;
“ SHOW CREATE TABLE event
”:
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
“ SHOW CREATE TABLE event_participant
”:
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
此外,查询本身看起来很丑陋,但这是生产系统上的遗留代码,因此我们不希望更改它(至少现在是这样)。
问题在于,event
表(在生产系统中)上大约有3600万条记录,因此由于 using temporary;using filesort
< / strong>处理(很遗憾,它们提供了EXPLAIN的这些输出,遗憾的是,我现在没有这些输出。稍后,我将尝试将其更新为这篇文章。)
客户通过添加索引来请求“快速修复”。目前,我们分别在full_session_id, pat_id, date
t的even
和user_id
的{{1}}上有索引。
因此,我正在考虑在event_participant
上创建一个复合索引 (pat_id, exe_id, full_session_id, date)
-该索引由联接中的字段组成(等效于?),然后进行分组,然后汇总(最少)份。
这只是一个主意,因为我们目前没有要测试的数据量,因此我们会尽力而为。
我的问题是:
在此先感谢您的帮助:)
更新:
我已经更新了两个相关表的完整表描述。
MySQL版本为5.1.69。但是我认为我们不必担心评论中提到的模棱两可的数据问题,因为似乎我们的数据不会有歧义。具体来说,对于每个full_session_id,仅返回一个“ event_exe.user_id”(这只是应用程序中的业务逻辑)
那么,您如何看待我的两个问题?