菜单开关

周梦康 发表于 2018-11-09 2151 次浏览 标签 : Mysql

看到数据库报警,查看慢 sql 日志看到

select id, content from table_name where status = 1 order by id asc limit 1328000, 1000

执行了 90 秒,扫描了 1329172 行。

改写成

select a2.id, a2.content from (select id from table_name where status = 1 order by id asc limit 1328000, 1000) a1, table_name a2 where a1.id=a2.id;

总结

这种数据量很大的表,应该是先做一个子查询查出 id(只会在索引里面扫描),然后关联查询,这样扫描的行数是限定的。而不会扫描表前面所有的行。

嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

[视频直播] PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

评论列表

回复 XDBruce 2018-11-16 13:21:34
厉害啊,我已经把你的博客加入我的友链了:https://www.xiebruce.top,然后,我再试试这个评论框能发markdown格式的图片不?
![timg (7).jpeg](https://img.xiebruce.top/2018/11/16/748cfc0aa595325022e4d423596706e4.jpeg)
回复 周梦康 2018-11-16 18:08:09
回复XDBruce: 简单的评论,没有支持图片的。不好意思哈。
回复 CCSnail 2019-03-06 11:38:54
老铁,这个跟查询出ID 再是用in 的效率相比如何?
回复 周梦康 2019-03-06 13:19:33
回复CCSnail: 差不多的,只不过这样少一次通讯传输。
回复 有木有是什么 2019-03-26 17:50:42
康神,请问下select id from table_name where status = 1 order by id asc limit 1328000, 1000,
这条语句是扫描了1000行,还是1328000+1000行。

我做了类似的测试,语句是:select id from t order by id asc limit 10000, 10,id是主键,得到的扫描结果是10010行,
是不是可以认为,虽然使用了覆盖索引,但是该扫描的行数仍然是不会少的。

只不过不需要回表,因此查询速度变快了。
回复 孤城浪子-PHP 2019-05-30 19:33:15
SELECT * FROM table_name a1 INNER JOIN (SELECT id FROM table_name ORDER BY id LIMIT 1328000,1000) a2 ON a1.id=a2.id这样的原理应该是一样的吧?
回复 coco购达人 2019-07-15 17:34:32
select a2.id, a2.content from (select id from table_name where status = 1 order by id asc limit 1328000, 1000) a1, table_name a2 where a1.id=a2.id; 这个id1328000 我还得先查出来啊 也很费时间