这感觉就像是“为我做作业”之类的问题,但我真的被困在这里,试图让这个查询对一个有很多行的表快速运行。这是一个显示架构(或多或少)的 SQLFiddle 。
我玩过索引,试图得到一些能显示所有必需列但没有取得多大成功的东西。这是create
:
CREATE TABLE `AuditEvent` (
`auditEventId` bigint(20) NOT NULL AUTO_INCREMENT,
`eventTime` datetime NOT NULL,
`target1Id` int(11) DEFAULT NULL,
`target1Name` varchar(100) DEFAULT NULL,
`target2Id` int(11) DEFAULT NULL,
`target2Name` varchar(100) DEFAULT NULL,
`clientId` int(11) NOT NULL DEFAULT '1',
`type` int(11) not null,
PRIMARY KEY (`auditEventId`),
KEY `Transactions` (`clientId`,`eventTime`,`target1Id`,`type`),
KEY `TransactionsJoin` (`auditEventId`, `clientId`,`eventTime`,`target1Id`,`type`)
)
和(一个版本)select
:
select ae.target1Id, ae.type, count(*)
from AuditEvent ae
where ae.clientId=4
and (ae.eventTime between '2011-09-01 03:00:00' and '2012-09-30 23:57:00')
group by ae.target1Id, ae.type;
我最终也得到了“使用临时文件”和“使用文件排序”。我尝试删除count(*)
并使用select distinct
,这不会导致“使用文件排序”。join
如果有办法返回计数,这可能没问题。
最初,决定跟踪创建审计记录时存在的目标的 target1Name 和 target2Name。我也需要这些名字(最近的就可以了)。
目前,查询(上面,缺少 target1Name 和 target2Name 列)在大约 5 秒内运行约 2400 万条记录。我们的目标是数亿,我们希望查询继续沿着这些路线执行(希望将其保持在 1-2 分钟内,但我们希望它做得更好),但我担心的是一次我们达到了它不会达到的大量数据(正在模拟额外的行)。
我不确定获得额外字段的最佳策略。如果我将列直接添加到select
查询中,我会丢失“使用索引”。我试着join
回到桌子上,它保留了“使用索引”,但大约需要 20 秒。
我确实尝试将 eventTime 列更改为 int 而不是 datetime,但这似乎并没有影响索引的使用或时间。