我在MySql数据库中有一个名为event的大表,有1000万条记录。
事件
CREATE TABLE `event` (
`eventId` BIGINT(20) NOT NULL AUTO_INCREMENT,
`eventTime` BIGINT(20) NOT NULL COMMENT 'ex: 1431201865000 (epoch is milliseconds)',
`sourceId` BIGINT(20) NOT NULL COMMENT 'ex: pole-code: 1 = JA005, patrolCarCode: 5000 = D4588',
PRIMARY KEY (`eventId`),
INDEX `eventTime` (`eventTime`),
INDEX `sourceId` (`sourceId`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=12343262;
我的小桌子有大约70条记录。
来源
CREATE TABLE `source` (
`sourceId` BIGINT(20) NOT NULL AUTO_INCREMENT,
`sourceName` VARCHAR(100) NOT NULL COMMENT 'ex: pole-code: JA005, patrolCarCode:D4588' COLLATE 'utf8_unicode_ci',
`sourceGps` VARCHAR(40) NULL DEFAULT NULL COMMENT 'Only for Fixed source (Poles) ex: 25.110227 N 55.239798 E, 24.993183 N 55.250382 E, 0.000000 N 0.000000 E' COLLATE 'utf8_unicode_ci',
`sourceAddress` VARCHAR(255) NULL DEFAULT NULL COMMENT 'Only for Fixed source (Poles) ex: Dubai, Bur Dubai, Burjman Center Interchange' COLLATE 'utf8_unicode_ci',
`sourceAltAddress` VARCHAR(255) NULL DEFAULT NULL COMMENT 'Alternative address, ex: address in arabic' COLLATE 'utf8_unicode_ci',
PRIMARY KEY (`sourceId`),
INDEX `sourceName` (`sourceName`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=71
;
数据
INSERT INTO `event` (`eventId`, `eventTime`, `sourceId`) VALUES
( 1474261476616, 33, 1),
( 1474261438966, 26, 2),
( 1474261479346, 25, 3),
( 1474261429952, 8, 5),
( 1474261477316, 33, 6)
INSERT INTO `source` (`sourceId`, `sourceName`, `sourceGps`, `sourceAddress`) VALUES
( 1, 'JA001', '25.110227 N 55.239798 E', 'Interchange'),
( 2, 'JA002', '25.110227 N 55.239798 E', 'Interchange'),
( 3, 'JA003', '25.110227 N 55.239798 E', 'Interchange'),
( 4, 'JA004', '25.110227 N 55.239798 E', 'Interchange'),
( 5, 'JA005', '25.110227 N 55.239798 E', 'Interchange')
任务
我想知道在特定时间之后发生的所有事件' 1474261429952'。
搜索到目前为止我已经制定了以下查询,这会带来结果,但速度很慢。 从表中检索结果大约需要1.5分钟。
SELECT count(source.sourceId) as 'totalEvents', source.sourceId, source.sourceGps,
source.sourceAddress from event inner join source on event.sourceId = source.sourceId
where eventTime >= 1474261429952 group by source.sourceId
解释结果:
请指导我如何加快速度。
感谢。
答案 0 :(得分:0)
您应该向events
表添加一个多列索引,涵盖字段sourceid, eventtime
(按此特定顺序)。
原因:MySQL可以在查询中为每个表使用一个索引(嗯,索引合并是一个小例外)。您在sourceid, eventtime
字段上有单独的索引,MySQL确实考虑使用这些索引,但是将它们解除(请参阅解释结果中的可能键和关键字段) - 可能单独使用它们都不够具有选择性。
通过另一个explain
创建索引后检查索引使用情况。您可能必须使用索引提示(use index
或force index
)来使MySQL使用新索引,尽管analyse table
也可能有助于此。
答案 1 :(得分:0)
虽然Shadow指出了多个字段索引与个人的问题,但我建议使用(eventtime,sourceid)的不同顺序而不是(sourceid,eventtime)。原因是...如果您的数据是10年,您仍然必须经历从旧到现在的每个来源。而不是仅仅跳到当前的日期范围。此外,您不是使用SOURCE表而不是EVENT进行分组,而是利用事件的索引,因为无论如何它们的键都是相同的。
由于来源是
SELECT
count(*) as 'totalEvents',
source.sourceId,
source.sourceGps,
source.sourceAddress
from
event
inner join source
on event.sourceId = source.sourceId
where
eventTime >= 1474261429952
group by
event.sourceId
如果你想尝试使用基于(SourceID,EventTime)的索引,我会改变查询并将SOURCE表放在第一个位置并写为......有趣的是你得到的时间性能差异回来。
SELECT
S.sourceId,
S.sourceGps,
S.sourceAddress,
count(*) as totalEvents
from
source S
join event E
on S.sourceId = E.sourceId
AND E.eventTime >= 1474261429952
group by
S.sourceId