美文网首页nosql
【Mysql】查询优化——减少回表操作

【Mysql】查询优化——减少回表操作

作者: 宅家学算法 | 来源:发表于2021-09-15 15:31 被阅读0次

    1 聚集索引和非聚集索引(普通索引)

      聚集索引:数据行的物理顺序与列值(一般是主键的那一列)的逻辑顺序相同,一个表中只能拥有一个聚集索引。叶子结点存储索引和行记录,聚簇索引查询会很快,因为可以直接定位到行记录。

    • 如果表设置了主键,则主键就是聚簇索引;
    • 如果表没有主键,则会默认第一个不为空,且唯一的列作为聚簇索引;
    • 以上都没有,则会默认创建一个隐藏的row_id作为聚簇索引

      非聚集索引:该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同,一个表中可以拥有多个非聚集索引。叶子节点存储聚簇索引值(主键id),需要扫码两遍索引树,先通过普通索引定位到主键值id,再通过聚集索引定位到行记录。

    2 回表查询

      回表查询可以理解为普通索引的查询,先定位主键值,再定位行记录,它的性能较扫一遍索引树更低。

    假设查询一张学生表(学号:主键id、姓名:普通索引id_name、年龄、班级),表中每一列都非空,查询“姓名”为A的学生信息时(学号,姓名,年龄),因为“姓名”上建了索引id_name,先从“姓名”非聚集索引id_name上,找到对应的主键id(学号)和“姓名”,然后根据主键id从聚集索引上找到对应的记录。此过程称为回表查询。

    3 减少回表查询

    3.1 索引覆盖

      索引覆盖,即将查询sql中的字段添加到联合索引里面,只要保证查询语句里面的字段都在索引文件中,就无需进行回表查询;

    对“姓名”和“年龄”列建立联合索引id_name_age,当查询“姓名”为A的学生信息时(姓名,年龄),因为叶子结点存储的值为主键id、姓名,年龄,所以从索引id_name_age上可以直接获取所需要的列值,不需要再依据主键id去查询列值,减少了回表过程。

      实际开发中,不可能把所有字段建立到联合索引,可根据实际业务场景,把经常需要查询的字段建立到联合索引中。

    3.2 索引下推(系统优化)

      在Mysql5.6的版本上推出,用于优化查询。在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。

    关闭索引下推:
    set optimizer_switch='index_condition_pushdown=off'

    3.3 子查询

      优化超多分页场景。查询条件放到子查询中,子查询只查主键id,然后使用子查询中确定的主键关联查询其他的属性字段。

    子查询使用主键id进行查询,则查询出来的记录包含了所有列值,然后利用right join将所需查询结果与子查询进行关联。

    select 各种字段 
    from table_name t1 
    right join 
    (select 主键 from table_name where 筛选条件 limit 0, 10)t2 
    on t1.主键 = t2.主键 
    

    相关文章

      网友评论

        本文标题:【Mysql】查询优化——减少回表操作

        本文链接:https://www.haomeiwen.com/subject/rfwkgltx.html