我有一个包含此架构的表:
CREATE TABLE `data_realtime` (
`id` mediumint(9) unsigned NOT NULL AUTO_INCREMENT,
`timestamp` int(10) NOT NULL,
`ticker_id` smallint(5) unsigned NOT NULL,
`price` decimal(7,2) unsigned NOT NULL,
`volume` mediumint(9) unsigned NOT NULL,
`bid` decimal(7,2) unsigned DEFAULT NULL,
`bid_sz` smallint(6) unsigned DEFAULT NULL,
`ask` decimal(7,2) unsigned DEFAULT NULL,
`ask_sz` smallint(6) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ticker_timestamp` (`ticker_id`,`timestamp`) USING BTREE,
CONSTRAINT `data_realtime_ibfk_2` FOREIGN KEY (`ticker_id`) REFERENCES `tickers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=11330043 DEFAULT CHARSET=latin1
我尝试运行一个简单的查询来按时间戳排序数据:
select * from data_realtime ORDER BY timestamp ASC
这需要2.5s(对于~4.5M行,最终将增加到大约12M行)。但如果我只是运行
select * from data_realtime
需要.25秒
我有一个关于时间戳的复合索引(带有ticker_id),我认为这有助于解决这个问题。
订购时,我该怎么做才能提高性能?
感谢。
修改: 要添加到原始问题,我有这个查询:
SELECT data_latest.*, data_1m.timestamp timestamp_1m, data_1m.price price_1m, data_1m.volume volume_1m FROM
(SELECT B.* FROM
(SELECT ticker_id, max(timestamp) max_timestamp FROM `data_rt` GROUP BY ticker_id)
A
LEFT JOIN
data_rt B
ON
A.ticker_id=B.ticker_id
and A.max_timestamp=B.timestamp)
data_latest
LEFT JOIN
data_rt data_1m
ON
data_latest.timestamp <= (data_1m.timestamp + (60*1) )
AND data_latest.timestamp > (data_1m.timestamp + 60*(1-0.5))
AND data_latest.timestamp>data_1m.timestamp
AND data_latest.ticker_id=data_1m.ticker_id
ORDER BY data_1m.timestamp ASC
在一组1M行上,它需要大约1.3秒。添加最后一个ORDER BY会大大增加时间。如果我改为ORDER BY时间戳,它只需要0.05秒。
使用临时列进行排序时,我可以做些什么?
答案 0 :(得分:1)
索引可以帮助加快查询速度;但只有当索引是MySQL将利用的索引时。复合索引(例如(a
,b
)上的索引将有助于同时涉及a
和b
的查询;例如WHERE a = N AND b = M
或ORDER BY a, b
。这样的索引甚至可以帮助仅涉及a
的查询。基本上,任何复合索引(a, b, .... n)
也可用作索引(a, b, .... n-1)
,(a, b, .... n-2)
,... (a, b)
和(a)
。
但是,根据实际数据值,它们的适用性会有很大差异(请参阅我对问题本身的第二条评论);它们不能用于索引中的后一个字段,而之前的字段也不涉及。 I.E.查询只涉及(a, b)
时,不使用b
。 _ (a,b,c, ...,n)
可以且经常用于涉及(a,b,n)
的查询,但只能与(a,b)
索引一样有效。