如何通过+巨大的限制偏移量优化MySQL订单

如何通过+巨大的限制偏移量优化MySQL订单,mysql,sql,optimization,Mysql,Sql,Optimization,表: 此查询运行quick enough0.015: 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; 但由于限位偏移

表:

此查询运行quick enough0.015:

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;
但由于限位偏移量较大,其运行速度非常慢2.215s:

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

我怎样才能摆脱巨大的极限偏移量

据我所知,在做了一点挖掘之后,您真的没有办法在数据库的配置中设置最大限制或诸如此类的内容。实现数据库的应用程序的开发人员将负责确保在应用程序的逻辑中建立最大值。

如果限制为10000,100 MySQL必须扫描10100条记录。如果你能记住你在窗口的位置,可能会更好:

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

在本例中:last_rating是上一个查询中的最后一个评级。

提高性能的最简单方法是按主键排序

因为你不能真正做到这一点与评级列,你可以作弊,而不是

创建此表:

SELECT uid
FROM test
WHERE rating > :last_rating
ORDER BY rating DESC LIMIT 0,100
然后将以下内容放入一个cron脚本中,该脚本每X时间段运行1分钟,5分钟。。。基本上,在更新速度和运行时间之间有一个很好的折衷:

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
现在,您可以跑得更快,而不是选择慢速跑步:

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`;

在这种情况下,评级不是已经是一个覆盖指数了吗?我没有否决投票。@Kolink,你的解决方案太棒了!请更正此查询:将uid值插入到_tmp_test_ranks中,按等级描述从测试顺序中选择uid;要插入_tmp_test_uid,请通过评级DESC从测试顺序中选择uid@Kolink,带有限制的最终选择查询也会运行**慢速**1.4s。不要使用LIMIT,而是像这样使用BETWEEN:从test_秩中选择uid,其中id在10000到10100之间,orderby id ASC。这真的很快。更正你的答案,我会接受的!临时表是什么?@Didar_Uranov:临时表是只存在于当前连接中的表。您可以编辑您的问题并在案例中添加查询时间吗?所以我们可以理解你说的慢和快是什么意思enough@Didar_Uranov你说得对。对不起,我是说评级现在修复。此技术适用于上一次下一次分页。我投你一票。我已经删除了上面的评论。请小心,因为这样可能会丢失一些结果:评级空间小于uid空间,并且不能确保每个评级值都有100个结果。我不会禁止任何人执行此类查询。只是想知道如何优化巨大的极限偏移量并消除它们。
SELECT `uid` FROM `test_ranks` WHERE `id` BETWEEN 10000 AND 10100 ORDER BY `id` ASC