美文网首页
MySQL索引

MySQL索引

作者: 米刀灵 | 来源:发表于2016-08-20 19:44 被阅读43次

    数据库索引的本质是数据结构,这种数据结构能够帮助我们快速的获取数据库中的数据。


    索引类型

    • 唯一索引
      看见名字我们就知道,唯一索引列中的值必须是唯一的。不过有一个例外,可以有且可以有多个Null。
    • 普通索引
      普通索引可以包括不止一列,一般把多个列组成的普通索引叫组合索引,也有把普通索引看成是只有一列的组合索引的。此外,在索引字符串时,可以只把前几位作为索引来提升效率。因为最左前缀,在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。
    • 主键
      主键必须唯一,不同的是不能有Null。而且一个表只能有一个主键。有很多人认为主键是唯一索引的一种,其实是不准确的。主键也可以是组合索引,只要组合的每条结果是唯一的。

    注:
    1.指定了AUTO_INCREMENT的列必须要建索引,不然会报错,主键,唯一键也是索引的一种不需要另外指定了。
    2.mysql中执行查询时,对一张表只能使用一个索引,如果我们在例如lname,fname,age上分别单独建立索引,执行查询时,只能使用一个索引,mysql会选择一个最严格(获得结果集记录数最少)的索引(所以这里使用组合索引效率更高)。


    creators表

    在NAME加上索引

    mysql> select * from creators where NAME = 'ABC';
    mysql> alter table creators add index NAME (NAME);
    mysql> select * from creators where NAME = 'ABC';
    mysql> SHOW PROFILES;
    

    设置索引

    ALTER TABLE table_name ADD INDEX index_name (column_list)
    ALTER TABLE table_name ADD UNIQUE (column_list)
    ALTER TABLE table_name ADD PRIMARY KEY (column_list)
    

    删除索引

    DROP INDEX index_name ON talbe_name
    ALTER TABLE table_name DROP INDEX index_name
    ALTER TABLE table_name DROP PRIMARY KEY
    第3条语句只在删除PRIMARY KEY索引时使用,如果没有创建PRIMARY KEY索引,但表具有一个或多个UNIQUE索引,则MySQL将删除第一个UNIQUE索引。
    

    查看索引

    mysql> show index from tblname;
    mysql> show keys from tblname;
    

    索引原则
    最左前缀匹配原则

    mysql> alter table creators add index cd_n_pn (CREATOR_DATE, NAME, PROFLIE_NAME);
    mysql> select * from creators where CREATE_DATE = '2046-09-01' and NAME = 'ABC' and PROFLIE_NAME = 'DEF';
    mysql> select * from creators where CREATE_DATE = '2046-09-01' and NAME = 'ABC';
    mysql> select * from creators where CREATE_DATE = '2046-09-01' and PROFLIE_NAME = 'DEF';
    mysql> select * from creators where NAME = 'ABC' and PROFLIE_NAME = 'DEF';
    

    前三个查询会用到索引,最后一个查询因为没用到组合索引的最左列,所以不会用到索引而是遍历了所有的数据,这就是最左前缀匹配。
    最左前缀匹配原则,是非常重要的原则,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的顺序可以任意调整。
    再举一个例子:
    假设你在表的state、city和zip数据列上建立了复合索引。索引中的数据行按照state/city/zip次序排列。这意味着,即使你在查询中只指定了state值,
    或者指定state和city值,MySQL也可以使用这个索引。因此,这个索引可以被用于搜索如下所示的数据列组合:state, city, zip或state, city或state。MySQL不能利用这个索引来搜索没有包含在最左前缀的内容。例如,如果你按照city或zip或city,zip来搜索,就不会使用到这个索引。如果你搜索给定的state和zip(索引的1和3列),该索引也是不能用于这种组合值的,只会利用索引来查找匹配的state从而缩小搜索的范围。所以根据最左前缀原则,这个组合索引相当于创建了(state)单列索引,(state, city)组合索引以及(state, city, zip)组合索引。

    选择区分度高的列作为索引
    区分度:count(distinct col)/count(*),,表示字段不重复的比例,越接近1区分度越高,唯一键或主键的区分度就是1。

    索引列不能参与计算
    保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引。

    尽量的扩展索引,不要新建索引
    比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可

    如何确定一个查询有没有走索引
    MySQL中自带命令行工具 explain 来查看一个sql语句是否了索引
    使用方式:

      explain select * from tb_test;
    

    关注的项:

    • type : 查询access的方式,表的连接类型
      index : 索引
      full : 全表扫描
      ref : 参照查询,也就是等值查询
      range : 范围查询
    • key : 本次查询最终选择使用哪个索引,NULL为未使用索引
    • key_len : 选择的索引使用的前缀长度或者整个长度
    • rows : 查询逻辑扫描过的记录行数
    • extra : 额外信息,主要是指fetch data的具体方式

    要点:
    1.唯一索引:唯一索引列中的值必须是唯一的,但可以有多个Null。主键(没有Null),唯一键也是唯一索引的一种不需要另外指定了。
    普通索引:普通索引可以包括不止一列,一般把多个列组成的普通索引叫组合索引。
    2.AUTO_INCREMENT:对于innodb,指定了AUTO_INCREMENT的非主键列必须要在建表时显式建立索引,如果是组合索引,必须是组合索引的第一列,不然会报错。主键,唯一键也是索引的一种不需要另外指定了。且一个表只能有一个AUTO_INCREMENT属性。
    3.添加索引:ALTER TABLE table_name ADD INDEX index_name (column_list)。
    删除索引:DROP INDEX index_name ON talbe_name 或 ALTER TABLE table_name DROP INDEX index_name。
    查看索引:show index from tblname。
    4.最左前缀匹配原则:在查询中必须有索引最左列才会使用到这个索引,(拿索引从左往右去匹配条件,直到遇到范围查询 >、<、between、like 就停止匹配,但它本身可以使用索引。)所以如果都是=,则查询条件的顺序是可以变的。
    5.用mysql自带的命令行工具 explain 来查看一个sql语句是否了索引,例如:explain select * from tb_test;


    参考:http://www.kuqin.com/shuoit/20161129/353112.html

    相关文章

      网友评论

          本文标题:MySQL索引

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