zoukankan      html  css  js  c++  java
  • 【索引】聚合索引

    1. 普通青年的索引使用方式

    假设我们有一个用户表 tb_user,内容如下:

    nameagesex
    jack 22
    rose 21
    tom 20
    ... ... ...

    执行SQL语句:

    SELECT name FROM tb_user WHERE age = 20;

    默认情况下,MySQL需要遍历整张表,才能找到符合条件的记录。如果在age字段上建立索引,那么MySQL可以很快找到所有符合条件的记录(索引本身通过B+树实现,查起来很快。简单起见,想象一下二分查找和遍历查找的区别。)

    2. 文艺青年的玩法

    2.1 用冗余的联合索引加速查询

    接着上面的例子,我们假设,tb_user表有一百万行,通常情况下,"WHERE age = 20"这样的语句,会返回几万行数据,实际测试下发现,速度不够快。

    原因是,MySQL根据索引查询到符合条件的记录后,还需要到表空间里一一查找这些记录(实际上,索引里同时记录了age字段和关联记录的物理行号),这意味着,MySQL必须读取表空间多达几万次,才能返回最终结果。

    聪明的你可能已经想到了,如果age字段的索引上有name字段的值话,MySQL就不用再费事地去访问表空间了。

    最终解决方案:建立联合索引,让MySQL直接从索引中取出name字段的值

    KEY `age_with_name` (`age`,`name`)

    注意这里的顺序,必须是先age后name,反之不行(除非你是根据name查age)。

    2.2 用冗余的联合索引加速排序

    依然是之前的表,假设要做这样的查询:

    SELECT * FROM tb_user ORDER BY age;

    因为我们在age上有索引,所以排序是很快的(索引的本质就是将表记录的物理行号按照特定规则排序)

    实际项目中,SQL可能比这个复杂些,比如:

    SELECT * FROM tb_user WHERE sex='' ORDER BY age;

    这个时候,age字段上的索引就派不上用场了。因为,age索引是面向整个表的,筛选后的表和age索引是对不上的。

    解决方案:依然是联合索引!

    KEY `age_with_name` (`sex`,`age`)

    这个联合索引,同时记录了sex和age,并且排序的规则是,先按sex排,sex相同时按age排。那么,通过"WHERE sex='男'",MySQL先对索引进行筛选,然后剩下的索引正好就是按照age排序的了。因此,整个SQL的排序速度依然很快。

  • 相关阅读:
    SE知识整理——泛型
    IDEA 运行 SpringMVC 项目分发控制器出现404解决方案。
    快速幂/欧拉降幂
    Leetcode(双指针专题)
    剑指offer
    ns3参考
    网络知识1:最后一公里/WiMax / 4G
    备份2
    shell入门
    ns3_gdb:协议里的函数是怎么被调用的
  • 原文地址:https://www.cnblogs.com/itplay/p/9523481.html
Copyright © 2011-2022 走看看