表:
CREATE TABLE `test` (
`uid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`rating` smallint(5) unsigned NOT NULL DEFAULT '100',
PRIMARY KEY (`uid`),
KEY `rating` (`rating`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
此查询运行得足够快(0.015秒):
SELECT uid FROM test ORDER BY rating DESC LIMIT 0,100
但是有很大的LIMIT偏移它运行得很慢(2.215s):
SELECT uid FROM test ORDER BY rating DESC LIMIT 10000,100
如何摆脱巨大的LIMIT抵消?!
答案 0 :(得分:6)
使用LIMIT 10000, 100
MySQL必须扫描10100条记录。如果您能记住窗口中的位置,那可能会更好:
SELECT uid
FROM test
WHERE rating > :last_rating
ORDER BY rating DESC LIMIT 0,100
在这种情况下:last_rating是上一次查询的最后一次评分。
答案 1 :(得分:1)
提高性能的最简单方法是ORDER BY主键。
由于您无法使用rating
列实际执行此操作,因此您可以作弊。
创建此表:
CREATE TABLE `test_ranks` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`uid` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
然后将以下内容放入一个每X次运行一次的cron脚本中(1分钟,5分钟...基本上是更新速度和运行时间之间的良好折衷):
CREATE TEMPORARY TABLE `_tmp_test_ranks` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`uid` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `_tmp_test_ranks` (`uid`) VALUES (SELECT `uid` FROM `test` ORDER BY `rating` DESC);
TRUNCATE `test_ranks`;
INSERT INTO `test_ranks` SELECT * from `_tmp_test_ranks`;
DROP TABLE `_tmp_test_ranks`;
现在,您可以更快地运行,而不是慢速运行选择:
SELECT `uid` FROM `test_ranks` WHERE `id` BETWEEN 10000 AND 10100 ORDER BY `id` ASC
答案 2 :(得分:0)
据我所知,在进行了一些挖掘之后,你真的没办法在数据库的配置或类似设置中设置最大限制。这将取决于实现数据库的应用程序的开发人员,以确保在应用程序的逻辑中建立最大值。