Mysql 有索引的情况下依然几乎扫描全表

2016-04-06 11:38:22 +08:00
 ivito
某张表有一个主键 id ,一个 item_id 字段,我对 item_id 字段加了索引,但是当我使用 select * from table_name limit 10000,20 查询时,发现 Rows_examined 为 10 万,大约等于全表大小。这是什么原因呢?
11617 次点击
所在节点    MySQL
22 条回复
wesley
2016-04-06 11:42:12 +08:00
需要加上 order by item_id
dongyado
2016-04-06 11:43:52 +08:00
你的查询语句都没用 id,item_id 肯定会全表扫描的啊。。。
keakon
2016-04-06 14:21:36 +08:00
没有 where 条件
sghcel
2016-04-06 14:27:35 +08:00
select item_id from table_name limit 10000,20 这样就不会全表扫描

具体原因看我的 blog: http://dorid.me/2016/02/03/mysql-limit-performance-optimize/
vincenttone
2016-04-06 14:30:51 +08:00
explain select * from table_name limit 10000,20;
explain select * from table_name limit 10000,20 order by id desc;
explain select * from table_name where item_id = 1 limit 10000,20;

挨个执行看看,你还需要花 20 分钟研究一下索引到底是什么
rqrq
2016-04-06 14:48:28 +08:00
先加上 order by id desc 试试,还是不行试试:
select * from table_name where id < (select min(id) from (select id from table_name order by id desc limit 10000) as tmp) limit 20
msg7086
2016-04-06 14:50:42 +08:00
MySQL 的分页是先读再丢,所以应该要读了扔了 10 万条记录以后再返回。
我自己是先读 ID 然后再用 ID IN () 去查表返回的。
davidzhang
2016-04-06 15:06:43 +08:00
因为你没有用到索引啊
stabc
2016-04-06 15:28:18 +08:00
treycheng
2016-04-06 15:33:36 +08:00
这个 limit 10000,20 做分页查询 首先会查处前面 10000 行的所有 select 的内容, 然后丢弃掉
分页查询 一般先查询你目标内容的主键 再通过主键查询目标行
sghcel
2016-04-06 15:49:37 +08:00
@treycheng 简而言之就是避免在丢弃的过程中回行
ivito
2016-04-06 17:36:48 +08:00
@dongyado 不会根据 Primary key 直接从从 B 数的左侧或右侧遍历吗,耗时不应该只是个扫描 Primary key 索引的耗时吗
ivito
2016-04-06 17:46:00 +08:00
@sghcel 结果展示的很有说服力,不过没有深入分析啊,还有时间数据 0.061 应该是 0.0061
jiehuangwei
2016-04-06 17:47:30 +08:00
看到这种SQL,就有想往死里打的冲动。。。。
wikimore
2016-04-06 17:50:37 +08:00
你这个 SQL 就是不全表扫 也不会太快 LIMIT 10000,20
wwek
2016-04-06 18:15:17 +08:00
大翻页问题
翻页从产品角度优化. 只给下一页 ,获取更多什么的
ihuotui
2016-04-06 18:25:03 +08:00
@msg7086 你说得太对了。 sql limit 执行过程。
suikator
2016-04-06 19:12:10 +08:00
@sghcel 文中一处好像有错,不是 0.0187 应该是 0.187 吧?
ivito
2016-04-06 20:56:19 +08:00
@rqrq 第一种无效,第二种方法快了一倍,但依然接近全表扫描,快出的部分应该是临时表只 select 了 id
rqrq
2016-04-06 23:01:14 +08:00
@ivito 你的目的就是要达到索引扫描?
说个题外话, 300ms 以内的响应速度我认为完全可以接受。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/268912

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX