2

桌子:

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.215 秒):

SELECT uid FROM test ORDER BY rating DESC LIMIT 10000,100

我怎样才能摆脱巨大的 LIMIT 偏移量?!

4

3 回答 3

6

使用LIMIT 10000, 100MySQL 必须扫描 10100 条记录。如果你能记住你在窗口中的位置,它可能会更好:

SELECT uid
FROM test
WHERE rating > :last_rating
ORDER BY rating DESC LIMIT 0,100

在这种情况下 :last_rating 是上一个查询的最后一个评级。

于 2012-05-05T06:10:52.730 回答
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
于 2012-05-05T06:11:03.980 回答
0

据我所知,在做了一些挖掘之后,你真的没有办法在数据库的配置中设置最大限制或类似的东西。这将取决于实现数据库的应用程序的开发人员,以确保在应用程序的逻辑中建立最大值。

于 2012-05-05T06:09:23.770 回答