zoukankan      html  css  js  c++  java
  • MYSQL: Handler_read_%参数说明

     
    环境:
    表t_feed_idx(user_id bigint, feed_id bigint, KEY (`user_id`,`feed_id`)) engine=innodb;
    表t_feed_info(feed_id bigint, PRIMARY KEY (`feed_id`), '其他列') engine=innodb;
    feed 总数 : 100000
    用户(ID:20000001) feed 数 : 200
     
    查询

    #########  单表
    > 全部扫描
        EXPLAIN SELECT * FROM `t_feed_info` AS i ORDER BY NULL LIMIT 0, 10;

    点击(此处)折叠或打开

    1. id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
    2. 1    SIMPLE    i    ALL    \N    \N    \N    \N    98734
        Handler_read_first + 1 : 从(主)键的第一个位置开始读取
        Handler_read_key + 1 : 根据第一个位置的KEY读1行,其他9行是根据叶节点的链表依次读取
        Handler_read_rnd_next +10 : 从主键的叶节点(行数据)中顺序读取10行

    > 索引扫描
        EXPLAIN SELECT * FROM `t_feed_info` AS i ORDER BY feed_id LIMIT 0, 10;

    点击(此处)折叠或打开

    1. id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
    2. 1    SIMPLE    i    index    \N    PRIMARY    8    \N    10
        Handler_read_first + 1 : 从(主)键的第一个位置开始读取
        Handler_read_key + 1 : 根据第一个位置的KEY读1行
        Handler_read_next + 9 : 按(主)键顺序依次读取之后的9行


        EXPLAIN SELECT * FROM `t_feed_info` AS i ORDER BY feed_id DESC LIMIT 0, 10;

    点击(此处)折叠或打开

    1. id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
    2. 1    SIMPLE    i    index    \N    PRIMARY    8    \N    10
        Handler_read_key + 1 : 根据第一个位置的KEY读1行
        Handler_read_last + 1 : 从(主)键的最后一个位置开始读取
        Handler_read_prev + 9 : 按(主)键顺序依次读取之前的9行


    > 索引覆盖扫描
        EXPLAIN SELECT feed_id FROM `t_feed_info` AS i ORDER BY feed_id LIMIT 0, 10;

    点击(此处)折叠或打开

    1. id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
    2. 1    SIMPLE    i    index    \N    PRIMARY    8    \N    10    Using index
        Handler_read_first + 1 : 从(主)键的第一个位置开始读取
        Handler_read_key + 1 : 根据第一个位置的KEY读1行
        Handler_read_next + 9 : 按(主)键顺序依次读取之后的9行

        EXPLAIN SELECT feed_id FROM `t_feed_info` AS i ORDER BY feed_id DESC LIMIT 0, 10;

    点击(此处)折叠或打开

    1. id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
    2. 1    SIMPLE    i    index    \N    PRIMARY    8    \N    10    Using index
        Handler_read_key + 1 : 根据第一个位置的KEY读1行
        Handler_read_last + 1 : 从(主)键的最后一个位置开始读取
        Handler_read_prev + 9 : 按(主)键倒序依次读取之后的9行


    ############### join
    # set @uid := '20000001';
    > WHERE + 排序
        # asc
        EXPLAIN SELECT * FROM `t_feed_idx` AS i
        LEFT JOIN `t_feed_info` AS f ON f.`feed_id`=i.`feed_id`
        WHERE i.user_id=@uid ORDER BY i.feed_id LIMIT 0, 10;

    点击(此处)折叠或打开

    1. id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
    2. 1    SIMPLE    i    ref    user_id    user_id    8    const    200    Using where; Using index
    3. 1    SIMPLE    f    eq_ref    PRIMARY    PRIMARY    8    z3.i.feed_id    1
        Handler_read_key + 11 : t_feed_idx 根据user_id读1次,t_feed_info根据feed_id读10次
        Handler_read_next + 9 : t_feed_idx按键顺序依次向后读取9个feed_id

        # desc
        EXPLAIN SELECT * FROM `t_feed_idx` AS i
        LEFT JOIN `t_feed_info` AS f ON f.`feed_id`=i.`feed_id`
        WHERE i.user_id=@uid ORDER BY i.feed_id desc LIMIT 0, 10;

    点击(此处)折叠或打开

    1. id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
    2. 1    SIMPLE    i    ref    user_id    user_id    8    const    200    Using where; Using index
    3. 1    SIMPLE    f    eq_ref    PRIMARY    PRIMARY    8    z3.i.feed_id    1
        Handler_read_key + 11 : t_feed_idx 根据user_id读1次,t_feed_info根据feed_id读10次
        Handler_read_prev + 9 : t_feed_idx按键倒序依次向前读取9个feed_id

    # 不好的查询方式: 
    > 使用被关联表t_feed_info的feed_id列进行排序
        EXPLAIN SELECT * FROM `t_feed_idx` AS i
        LEFT JOIN `t_feed_info` AS f ON f.`feed_id`=i.`feed_id`
        WHERE i.user_id=@uid ORDER BY f.feed_id LIMIT 0, 10;  

    点击(此处)折叠或打开

    1. id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
    2. 1    SIMPLE    i    ref    user_id    user_id    8    const    200    Using index; Using temporary; Using filesort
    3. 1    SIMPLE    f    eq_ref    PRIMARY    PRIMARY    8    z3.i.feed_id    1
        Handler_read_key + 201 : t_feed_idx 根据user_id读1次,t_feed_info根据feed_id读200次
        Handler_read_next + 200 : t_feed_idx按键顺序依次读取199个feed_id. 额外的1次是??
        Handler_read_rnd + 10 : filesort后每行位置都是固定的,limit 10取10行
        Handler_read_rnd_next + 201: filesort全表遍历读取temporary表中的200行,进行排序; 额外的1是EOF标志位;

        Using temporary; Using filesort 原因: 无法使用t_feed_idx表的索引
                1>先查询表t_feed_idx中满足@uid的200行与表t_feed_info进行join,将结果保存在temporary表
                    Handler_read_key + 201, Handler_read_next + 200
                2>然后对临时表排序;
                    Handler_read_rnd_next + 201
                3>取前10个。
                     Handler_read_rnd + 10

    > where条件放在join中
        EXPLAIN SELECT * FROM `t_feed_idx` AS i
        LEFT JOIN `t_feed_info` AS f ON f.`feed_id`=i.`feed_id` AND i.user_id=@uid 
        ORDER BY i.`feed_id` DESC LIMIT 0, 10;  

    点击(此处)折叠或打开

    1. id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
    2. 1    SIMPLE    i    index    \N    user_id    16    \N    100396    Using index; Using filesort
    3. 1    SIMPLE    f    eq_ref    PRIMARY    PRIMARY    8    z3.i.feed_id    1
        Handler_read_first + 1 : 从表t_feed_idx 中user_id索引开始位置进行读取
        Handler_read_key + 11 : t_feed_idx 根据user_id读1次,t_feed_info根据feed_id读10次
        Handler_read_rnd_next + 100001: filesort全表遍历读取表t_feed_idx 中user_id索引的100000行,进行排序; 额外的1是EOF标志位;

        没有 Using temporary 是因为先对t_feed_idx的索引user_id进行排序,然后再join
        Using filesort 原因:
                无法使用t_feed_idx表的索引
                1>先对表t_feed_idx排序,取10个feed_id
                    Handler_read_first + 1, Handler_read_key + 1, Handler_read_rnd_next + 100001
                2>然后根据feed_id与表t_feed_info进行join
                    Handler_read_key + 10


    参考: http://www.mysqlperformanceblog.com/2010/06/15/what-does-handler_read_rnd-mean/
  • 相关阅读:
    unsupported jsonb version number 123
    如何在MPlayer上支持RTSP
    TDengine 时序数据库的 ADO.Net Core 提供程序 Maikebing.EntityFrameworkCore.Taos
    如何使用IoTSharp对接ModBus?
    如何从源码启动和编译IoTSharp
    Asp.Net Core 自动适应Windows服务、Linux服务、手动启动时的内容路径的扩展方法
    MQTTnet 的Asp.Net Core 认证事件的扩展
    Asp.Net Core 中利用QuartzHostedService 实现 Quartz 注入依赖 (DI)
    The remote certificate is invalid according to the validation procedure 远程证书验证无效
    settings插拔式源码
  • 原文地址:https://www.cnblogs.com/zengkefu/p/5685793.html
Copyright © 2011-2022 走看看