› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
ivito
V2EX  ›  MySQL

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

  •  
  •   ivito ·
    fireboyvt · Apr 6, 2016 · 13065 views
    This topic created in 3864 days ago, the information mentioned may be changed or developed.
    某张表有一个主键 id ,一个 item_id 字段,我对 item_id 字段加了索引,但是当我使用 select * from table_name limit 10000,20 查询时,发现 Rows_examined 为 10 万,大约等于全表大小。这是什么原因呢?
    22 replies  •  2016-04-07 11:16:09 +08:00
    wesley
    wesley
    Apr 6, 2016
    1
    需要加上 order by item_id
    dongyado
    dongyado
    Apr 6, 2016
    2
    你的查询语句都没用 id,item_id 肯定会全表扫描的啊。。。
    keakon
    keakon
    Apr 6, 2016
    3
    没有 where 条件
    sghcel
    sghcel
    Apr 6, 2016❤️1
    4
    select item_id from table_name limit 10000,20 这样就不会全表扫描

    具体原因看我的 blog: http://dorid.me/2016/02/03/mysql-limit-performance-optimize/
    vincenttone
    vincenttone
    Apr 6, 2016
    5
    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
    rqrq
    Apr 6, 2016
    6
    先加上 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
    msg7086
    Apr 6, 2016❤️2
    7
    MySQL 的分页是先读再丢,所以应该要读了扔了 10 万条记录以后再返回。
    我自己是先读 ID 然后再用 ID IN () 去查表返回的。
    davidzhang
    davidzhang
    Apr 6, 2016
    8
    因为你没有用到索引啊
    treycheng
    treycheng
    Apr 6, 2016
    10
    这个 limit 10000,20 做分页查询 首先会查处前面 10000 行的所有 select 的内容, 然后丢弃掉
    分页查询 一般先查询你目标内容的主键 再通过主键查询目标行
    sghcel
    sghcel
    Apr 6, 2016
    11
    @treycheng 简而言之就是避免在丢弃的过程中回行
    ivito
    ivito
    OP
    Apr 6, 2016
    12
    @dongyado 不会根据 Primary key 直接从从 B 数的左侧或右侧遍历吗,耗时不应该只是个扫描 Primary key 索引的耗时吗
    ivito
    ivito
    OP
    Apr 6, 2016
    13
    @sghcel 结果展示的很有说服力,不过没有深入分析啊,还有时间数据 0.061 应该是 0.0061
    jiehuangwei
    jiehuangwei
    Apr 6, 2016
    14
    看到这种SQL,就有想往死里打的冲动。。。。
    wikimore
    wikimore
    Apr 6, 2016
    15
    你这个 SQL 就是不全表扫 也不会太快 LIMIT 10000,20
    wwek
    wwek
    Apr 6, 2016
    16
    大翻页问题
    翻页从产品角度优化. 只给下一页 ,获取更多什么的
    ihuotui
    ihuotui
    Apr 6, 2016
    17
    @msg7086 你说得太对了。 sql limit 执行过程。
    suikator
    suikator
    Apr 6, 2016 via Android
    18
    @sghcel 文中一处好像有错,不是 0.0187 应该是 0.187 吧?
    ivito
    ivito
    OP
    Apr 6, 2016
    19
    @rqrq 第一种无效,第二种方法快了一倍,但依然接近全表扫描,快出的部分应该是临时表只 select 了 id
    rqrq
    rqrq
    Apr 6, 2016
    20
    @ivito 你的目的就是要达到索引扫描?
    说个题外话, 300ms 以内的响应速度我认为完全可以接受。
    sghcel
    sghcel
    Apr 7, 2016
    21
    @ivito 深入分析就是丢弃的过程中产生的回行,这是根本原因
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2756 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 61ms · UTC 00:30 · PVG 08:30 · LAX 16:30 · JFK 19:30
    ♥ Do have faith in what you're doing.