mysql - 优化 MySQL 表以获得更快的 ORDER BY 性能

标签 mysql sql-order-by

我有一个具有以下架构的表:

    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 秒(大约 450 万行,最终将增加到大约 1200 万行)。但如果我只是运行

select * from data_realtime

需要 0.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 会大大增加时间。如果我改为按时间戳排序,则只需 0.05 秒。

使用临时列排序时我可以做哪些改进?

最佳答案

索引可以帮助加快查询速度;但只有当索引是 MySQL 才会利用的索引时。复合索引(例如 (a, b) 上的索引)将有助于同时涉及 ab 的查询;例如 WHERE a = N AND b = MORDER BY a, b。这样的索引甚至有助于只涉及 a 的查询。基本上,任何复合索引 (a, b, .... n) 也充当索引 (a, b, .... n-1), (a,b,... n-2),...(a,b)(a)

但是,它们的适用性根据实际数据值的不同而有很大差异(请参阅我对问题本身的第二条评论);当不涉及前面的字段时,它们不能用于索引中后面的字段。 IE。当查询仅涉及 b 时,不使用 (a, b)。 _(a,b,c, ...,n) 可以并且经常用于涉及 (a,b,n) 的查询,但只能有效地发挥作用作为 (a,b) 索引。

关于mysql - 优化 MySQL 表以获得更快的 ORDER BY 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48268813/

相关文章:

php - 如何从单个查询中获取数组中的值

mysql - ajax 和发布非拉丁字符的问题

php - 使用 PHP 存储视频时出现未定义索引错误

mysql - 限时再下单

MySQL JOIN 3 个表

Mysql虚拟机远程连接失败

MYSQL - 按价格+特定第一个结果排序

mysql - rails : order query by has and belongs to many presence

php - Mysql - Laravel - order by 和 rownum 位置在 2 个查询中不同步

MySQL 按当天的优先级排序