我有一个具有此模式的表:
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.5秒(约4.5米的行,最终将增加到约12米的行)。但如果我只是跑
select * from data_realtime
需要25秒
我在timestamp上有一个复合索引(带有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
在一组1米的行上,大约需要1.3秒。把最后一个订单加起来会大大增加时间。如果我改为按时间戳订购,只需要0.05秒。
使用临时列进行排序时,我可以做些什么改进?
1条答案
按热度按时间tv6aics11#
索引可以帮助加快查询速度;但只有当索引是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)
.然而,它们的适用性是否会因实际数据值的不同而有很大差异(见我对问题本身的第二点评论);它们不能用于索引中的后一个字段,因为前面的字段不涉及。即。
(a, b)
当查询只涉及b
. _(a,b,c, ...,n)
可以并且经常将用于涉及(a,b,n)
但只会像(a,b)
索引。