索引概念详解

一、聚集(clustered)索引,也叫聚簇索引
在这里插入图片描述
注:第一列的地址表示该行数据在磁盘中的物理地址,后面三列才是我们SQL里面用的表里的列,其中id是主键,建立了聚集索引。
结合上面的表格就可以理解这句话了吧:数据行的物理顺序与列值的顺序相同,如果我们查询id比较靠后的数据,那么这行数据的地址在磁盘中的物理地址也会比较靠后。而且由于物理排列方式与聚集索引的顺序相同,所以也就只能建立一个聚集索引了。
在这里插入图片描述
聚集索引实际存放的示意图

从上图可以看出聚集索引的好处了,索引的叶子节点就是对应的数据节点(MySQL的MyISAM除外,此存储引擎的聚集索引和非聚集索引只多了个唯一约束,其他没什么区别),可以直接获取到对应的全部列的数据,而非聚集索引在索引没有覆盖到对应的列的时候需要进行二次查询,后面会详细讲。因此在查询方面,聚集索引的速度往往会更占优势。

非聚集(unclustered)索引
定义:该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同,一个表中可以拥有多个非聚集索引。

其实按照定义,除了聚集索引以外的索引都是非聚集索引,只是人们想细分一下非聚集索引,分成普通索引,唯一索引,全文索引。如果非要把非聚集索引类比成现实生活中的东西,那么非聚集索引就像新华字典的偏旁字典,他结构顺序与实际存放顺序不一定一致。
在这里插入图片描述
非聚集索引的二次查询问题

非聚集索引叶节点仍然是索引节点,只是有一个指针指向对应的数据块,此如果使用非聚集索引查询,而查询列中包含了其他该索引没有覆盖的列,那么他还要进行第二次的查询,查询节点上对应的数据行的数据。

在这里插入图片描述
使用以下语句进行查询,不需要进行二次查询,直接就可以从非聚集索引的节点里面就可以获取到查询列的数据。

select id, username from t1 where username = ‘小明’

select username from t1 where username = ‘小明’
但是使用以下语句进行查询,就需要二次的查询去获取原数据行的score:

select username, score from t1 where username = ‘小明’
在SQL Server里面查询效率如下所示,Index Seek就是索引所花费的时间,Key Lookup就是二次查询所花费的时间。可以看的出二次查询所花费的查询开销占比很大,达到50%。

mysql 主键和唯一索引的区别
主键是一种约束,唯一索引是一种索引,两者在本质上是不同的。
主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键。
唯一性索引列允许空值,而主键列不允许为空值。
主键列在创建时,已经默认为非空值 + 唯一索引了。
主键可以被其他表引用为外键,而唯一索引不能。
一个表最多只能创建一个主键,但可以创建多个唯一索引。
主键和唯一索引都可以有多列。
主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。

二、索引的分类
1、唯一索引:表上一个字段或者多个字段的组合建立的索引,这些字段组合起来能够确定唯一,允许存在空值(只允许存在一条空值)
2、非唯一索引:表上一个字段或者多个字段的组合建立的索引,可以重复,不需要唯一
3、主键索引:(主索引)根据主键pk_clolum(length)建立索引,不允许重复,不允许空值;
4、聚合索引:表中记录的物理顺序与键值的索引顺序相同
5、非聚合索引:表中记录的物理顺序与键值的索引顺序无关
6、全文索引:在某个字段设置全文索引后,根据特定语法查找满足条件的字段;
7、普通索引:用表中的普通列构建的索引,没有任何限制
8、组合索引:用多个列组合 构建的索引,但是在使用过程中有诸多规则,遵循最左前缀原则,顺序至关重要
9、Hash索引(Memory存储引擎)是通过索引列的值计算出hashCode,之后在相应的物理位置存取索引列的值,由于hashCode的唯一性,因此Hash索引不能进行范围查找或者是顺序查找。

三、InNoDB与MyISAM异同

1InnoDB 支持事务,支持行级别锁定,支持 B-tree、Full-text (InNoDB1.2.X版本开始支持全文搜索的技术)等索引,不支持 Hash 索引,但是给了又有一个特殊的解释:InnoDB存储引擎 是支持hash索引的,不过,我们必须启用,hash索引的创建由InnoDB存储引擎引擎自动优化创建,是数据库自身创建并使用,DBA(数据库管理员)无法干预;
2MyISAM 不支持事务,支持表级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;
3Memory 不支持事务,支持表级别锁定,支持 B-tree、Hash 等索引,不支持 Full-text 索引;
4MyISAM引擎不支持外键,InnoDB支持外键
5MyISAM引擎的表在大量高并发的读写下会经常出现表损坏的情况
6、对于count()查询来说MyISAM更有优势,MyISAM直接通过计数器获取。InnoDB需要通过扫描全部数据,虽然InNoDB存储引擎是支持行级别所,InNoDB是行级别锁,是where对他主键是有效,非主键的都会锁全表的
7MyISAM引擎的表的查询、更新、插入的效率要比InnoDB高,如果你的数据量是百万级别的,并且没有任何的事务处理,那么用MyISAM是性能最好的选择。并且MyISAM可以节省很多内存,因为MyISAM索引文件是与数据文件分开放置,并且索引是有压缩,内存使用率提高不少
8、平台承载的大部分项目是读多写少的项目,MyISAM读性能比InNoDB强很多

四、什么叫做覆盖索引?
在了解覆盖索引之前我们先大概了解一下什么是聚集索引(主键索引)和辅助索引(二级索引)

   聚集索引(主键索引):
       聚集索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的记录数据。
       聚集索引的叶子节点称为数据页,聚集索引的这个特性决定了索引组织表中的数据也是索引的一部分。
   辅助索引(二级索引):
       非主键索引,叶子节点=键值+书签。Innodb存储引擎的书签就是相应行数据的主键索引值。
    再来看看什么是覆盖索引,有下面三种理解:

解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
解释二: 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫 做覆盖索引。
解释三:是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也即,索引包含了查询正在查找的所有数据)。
  不是所有类型的索引都可以成为覆盖索引。覆盖索引必须要存储索引的列,而哈希索引、空间索引和全文索引等都不存储索引列的值,所以MySQL只能使用B-Tree索引做覆盖索引

五、组合索引(覆盖索引)
基于多个字段创建的索引就是组合索引。

组合索引规则:
1、最左原则:索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。(电话簿中利用姓名查找人,姓和名分别是不同的列,知道姓电话簿有用,知道姓知道名电话簿有用,知道名不知道姓电话簿无用)

补充:
key_len:EXPLAIN执行计划中有一列 key_len用于表示本次查询中,所选择的索引长度有多少字节,通常我们可借此判断联合索引有多少列被选择了。

六、索引失效

1、在where后使用or,导致索引失效(尽量少用or)
2、使用like ,以%结尾不会失效
3、不符合最左原则
4、如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
5、 使用in导致索引失效
6、使用mysql内部函数导致索引失效,可能会导致索引失效。
7、如果MySQL估计使用索引比全表扫描更慢,则不使用索引

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值