• MySql索引


    索引

    聚集索引和普通索引

            MySQL数据库的B+tree索引可以分为两大类,一类叫聚集索引,一类叫非聚集索引(普通索引)。

            InnoDB存储引擎表是索引组织表,聚集索引其实就是一种索引组织形式,索引键值的逻辑顺序决定了表数据行的物理存储顺序。聚集索引叶子节点存放表中所有行数据记录的信息,所以经常会说数据即索引,索引即数据,这是针对聚集索引来说的。在创建一张表时,要显示地为表创建一个主键(聚集索引),如果不主动创建主键,那么InnoDB会选择第一个不包含有null值地唯一索引作为主键。如果连唯一索引都没有,InnoDB就会为该表默认生成一个6字节的rowid作为主键。

            普通索引在叶子节点并不包含所有行的数据记录,只是会在叶子节点存有自己本身的键值和主键的值。在检索数据时,通过普通索引叶子结点上的主键来获取想要查找的行数据记录。

    主键索引和唯一索引

            主键索引就是聚集索引,每张表中有且仅有一个主键,可以由表中一个或者多个字段组成。主键索引必须满足三个条件,主键值必须唯一;不能包含null值,一定要保证该值是自增属性。使用自增列作为主键,可以保证写入的数据顺序也是自增的,这就在很大程度上提高了存取效率。

    创建主键的语法:

    alter table table_name add primary key(column);

    唯一索引是约束条件的一种,其实就是不允许有重复的值,但是可以允许有null值。上面说过表中只能有一个主键,但是唯一索引可以有多个。

    创建唯一索引的语法:

    alter table table_name add unique (column);

    覆盖索引

    MySQL只需要通过索引就可以返回查询所需要的数据,而不必在查询到索引之后再去回表查询数据了,这样就减少了大量的I/O操作,查询速度也是相当快。在执行计划的extra列中会出现Using index的关键字。比如查询语句select id from t where name='name11'G;,在这条查询语句中,想要检索主键id字段,而且在查询条件中name字段是普通索引,之前讲过普通索引中包含主键的值,相当于(name, id)索引,那么这条语句就使用了覆盖索引,出现了Using index。

    注意: 如果使用覆盖索引,一定要让select 列出所需要的列,坚决不可以直接写出select * 。

    联合索引

    联合索引又叫复合索引,是在表中两个或者两个以上的列上创建的索引。利用索引中的附加列,可以缩小检索的段池范围,更快的搜索到数据。创建语法和普通索引的创建一样。例如为表t的c1, c2字段创建一个联合索引语法:

    create index idx_c1_c2 on t (c1, c2);

    联合索引在使用的过程中,必须满足最左前缀原则。一般把选择性高的列放在前面。一条查询语句可以只使用索引中的一部分,但是必须是从最左侧开始。

    可以用到c1索引和c1, c2索引。

    以下查询可以使用到索引:

    select * from t where c1=某值;

    select * from t where c2=某值 and c1=某值;

    select * from t where c1=某值 and c2 in (某值,某值);

    select * from t order by c1, c2;

    select * from t where c1=某值 order by c2;

    反之,使用不到索引的情况:

    select * from t where c2=某值;

    select * from t where c2=某值 order by c1;

    还有一种特殊的情况:

    select * from t where c1=某值 or c2=某值;

    虽然c1字段在前,但是这种情况是不能使用到索引的。这种情况可以在c1,c2字段上面建立两个单列索引。 

    哈希索引

    哈希索引采用哈希算法,把键值换算成新的哈希值,这里需要注意哈希索引只能进行等值查询,不能进行排序,模糊查找,范围查询等。检索时不需要像B+tree那样从根节点到叶子节点逐级查找,只需要一次哈希算法即可立刻定位到相应的位置,查询速度非常快。例如,select * from zs where city_id=100 这样一条语句。哈希过程如下图:

    索引的总结

    索引的优点:

    1) 提高数据检索的效率

    2) 提高聚合函数的效率

    3) 提高排序效率

    4) 使用覆盖索引可以避免回表

    索引创建的四个不要:

    1) 选择性低的字段不要创建索引(例如, 性别sex, 状态status)

    2) 很少查询的列不要创建索引(项目初期就要确定好)

    3) 大数据类型字段不要创建索引

    4) 尽量避免使用NULL,应该指定列为NOT NULL(在MySQL中,含有空值的列很难进行查询优化,它们会使得索引,索引的统计信息及比较运算更加复杂,可以使用空字符串代替空值)

    使用不到索引的情况:

    1)通过索引扫描的行记录超过全表的30%,优化器就不会走索引,而变成全表扫描,

    2) 联合索引中,第一个查询条件不是最左索引列

    3) 联合索引中,第一个索引列使用范围查询,只能使用到部分索引

    4)联合索引中,第一个查询条件不是最左前缀列

    5)模糊查询条件列最左以通配符%开始

    6)两个单列索引,一个用于检索,一个用于排序。这种情况下只使用一个索引。因为查询语句最多只能使用一个索引,考虑建立联合索引。

    7)查询字段上面有索引,但是使用了函数运算。

  • 相关阅读:
    Redhat Enterprise Linux 磁带机质朴把持
    Lotus 认证介绍
    Delphi 与 DirectX 之 DelphiX(1): 安装测试
    关于结构体与类型转换的一点小技巧
    提取网页中的所有链接、点击第 n 个链接 回复 "刘丽" 的问题
    Delphi 与 DirectX 之 DelphiX(2): DelphiX 各单元概览
    模拟点击网页中的按钮 回复 "starcraft_ly" 的问题
    求助! 谁有 《inside delphiX》这本书?
    类型转换出现在赋值运算符左边的情况
    绘制一个钢琴键盘
  • 原文地址:https://www.cnblogs.com/xiebinbbb/p/13865668.html
Copyright © 2020-2023  润新知