• MySQL索引


    索引的种类


    普通索引

    最基本的索引,没有任何限制。

    唯一索引

    索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。

    主键索引

    是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。建立主键时就自动生成了该索引。

    组合索引

    指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。遵循最左匹配原则。

    全文索引

    主要用来查找文本中的关键字,而不是直接与索引中的值相比较

    索引的类型

    FULLTEXT

    即为全文索引,目前只有MyISAM引擎支持。目前只有 CHAR、VARCHAR ,TEXT 列上可以创建全文索引。

    HASH

    由于HASH的唯一(几乎100%的唯一)及类似键值对的形式,很适合作为索引。HASH索引可以一次定位,不需要像树形索引那样逐层查找,因此具有极高的效率。

    BTREE

    要讲B+树,就要先讲讲B树的规则:

     

    而B+树是B树变体,其定义基本与B树相同,除了:

    非叶子节点的子树指针与关键字个数相同

    非叶子节点的的子树指针P[i],指向关键字值(K[i],K[i+1])的子树

    非叶子节点只用来索引,数据都保存在叶子节点中

    所有叶子节点均有一个链指针指向下一个叶子节点

     

    B+树如图所示:

     

    RTREE

     RTREE在mysql很少使用,仅支持geometry数据类型,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种。

     

    使用HASH索引的缺点

    (1)Hash 索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询。
    由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。

    (2)Hash 索引无法被用来避免数据的排序操作。
    由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;

    (3)Hash 索引不能利用部分索引键查询。

    对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
    (4)Hash 索引在任何时候都不能避免表扫描。
    前面已经知道,Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
    (5)Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。
    对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。

    使用B+树索引的优点


    (1)B+树的磁盘读写代价更低

    b+树的非叶子节点只保存了关键字的数据,没有保存具体的信息,这样内存中一次性读取的关键字就更多,相对来说IO读写速度也就降低了

    (2)B+树的查询效率更加稳定

    由于内部节点并不是最终指向内容的节点,而只是叶子节点中关键字的索引,所以任何关键字必须从根节点到叶子节点,是稳定的

    (3)B+树更有利于对数据库的扫描

    b树提高了IO性能,但没有解决效率低下的问题,b+树只需要遍历叶子节点就能进行数据库常见的范围查询

    联合索引的最左匹配原则

    1、最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

    2、=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式

    我对最左匹配原则的理解为每个索引点都保存了联合索引项,以建立了(a,b,c)索引为例,会从左到右建立B+树,也就是说先从a进行查找,如果a是等值查找,找到a会继续从b进行查找,b如果也是等值查找,找到b后会继续从c进行查找,这样a,b,c都走到了索引。但是如果从a开始查找的时候,若a是范围查找,还是能依据索引进行查找,但根据最左匹配原则的第一条,会停止后面的匹配,也就是说查询去a的范围后,后面b的值和c的值都只能去a的范围中进行查询,走不了索引了。
    下面就能很好理解为什么下面两个查询语句都能走索引了。
    select * from test where a=10 and b =10 and c<10;
    select * from test where a<10 and b <10 and c<10;

      

    聚集索引和非聚集索引

    MyISAM的索引是非聚集索引,具体表现在结构与数据的分离。MyISAM的B+树的叶子结点的data域中存储的是地址,与该地址相映射的是另一个文件中所存储的数据。因此需要从主键值获取到数据地址,再从地址获取具体数据。MyISAM的辅助索引与主键索引区别不大,只是主键索引的key不能重复。

    InnoDB的索引是聚集索引,因为InnoDB的B+树的叶子结点的data域存储的就是数据,省去了根据地址查找数据的步骤。InnoDB的辅助索引的data域就是主键的数值,所以进行辅助索引前,会先获取主键的信息,所以主键不宜过大,因为会到致辅助索引过大,很消耗资源。InnoDB的主键是主键索引,非主键是辅助索引。

    索引是建立越多越好吗? 


    数据量小的表不需要建立索引,建立索引会增加额外的索引开销

    数据变更需要维护索引,因此需要更多的索引意味着更多的维护成本

    更多的索引意味着也需要更多的空间

    索引的注意要点

    1.列上进行函数计算将不会使用索引;
    2.对于创建索引的列,避免存储NULL,NULL会使索引更加复杂、效率变低,可以使用NOT NULL进行约束;
    3.对于模糊查询like '%abc%',将不会使用索引,而like 'abc%'将会使用索引;
    4.对于not in、not exists、!=等负向查询将不会使用索引;
    5.每次查询只使用一个索引,如果where条件使用了索引,order by将不再使用索引;
    6.对于where子句中有多个查询条件的,单列索引的效率不如复合索引,因为查询每次只能使用一个索引;
    7.MySQL只对以下操作符才使用索引:<、<=、=、>、>=、between、in,但是需要注意in的范围值不要太多;
    8.union all可以使用索引,但本身效率不是很高,不建议使用;
    9.列上进行类型转换的将不会使用索引;
    10.老版本MySQL对OR条件不使用索引,新版本才支持,不建议使用OR。

    参考:

    https://www.cnblogs.com/luyucheng/p/6289714.html

    https://www.cnblogs.com/yuan-shuai/p/3225417.html

  • 相关阅读:
    iOS使用技能
    iOS 视频播放的简单使用
    iOS中二维码的生成与使用(入门篇)
    正则表达式的小总结
    最近项目中巧遇的几个好工具,分享一下
    Foundation与coreFoundation的相互转换
    iOS实用技能扩展-集成支付宝
    iOS实用技能扩展-静态库的制作与简单使用
    数据存储的三种方式
    Magento获取IP地址
  • 原文地址:https://www.cnblogs.com/lzxin/p/10406073.html
Copyright © 2020-2023  润新知