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(只会在索引里面扫描),然后关联查询,这样扫描的行数是限定的。而不会扫描表前面所有的行。
开发同学按照传达的精神使用了上次说的大表翻页优化的方式在做翻页查询了。执行时间97秒。
select a2.id,a2.keyword,a2.url from (select id from table_name order by id asc limit 73575000, 5000) a1, table_name a2 where a1.id=a2.id
select count(*) from table_name;
执行查看表总数都执行了70292.60ms
,总行数是118345950
行。
对于这种表,做大表翻页优化,也已经无效了。那应该怎么弄呢?
我们先不去纠结历史原因,为什么没有分表。着眼解决当前的问题。
问下具体开发的同学,是在全表扫描这个表是否命中一些违禁词。这样就好办了。我们只需要“分段扫描就行了呀”
select id from table_name where id>73575000 order by id asc limit 0, 5000
执行时间19.63ms
select a2.id,a2.keyword,a2.url from (select id from table_name where id>73575000 order by id asc limit 0, 5000) a1, table_name a2 where a1.id=a2.id
执行时间26.35ms
,又可以愉快的玩耍了。
或者直接
select id,keyword,url from table_name where id>73575000 order by id asc limit 0, 5000
总结
为什么可以这样写呢,因为这次是循环扫描,本次扫描就知道下次查询的起始 id。不会跳着访问。
欢迎大家学习,交流