mysql之索引组织表

 1.二叉树/平衡树.B-tree.B+tree.B*tree

:最上一层是根节点.最底下一层是叶子节点.(一般左边节点小于右边节点)

二叉树:每个节点最多只能有两个分支,一般只用于教材.二叉树的深度不可控,造成遍历数据时IO次数不可控.数据量大了,树的深度会太大.

二叉树的变种:BTREE(又写成B-tree),B+treeB*tree.

B-treebalance-tree:平衡树:假设1个节点的子节点是5,平衡树是必须上层节点都满了,才可加到下层.这样树的深度就得到了控制.B-tree除了在叶子节点保存数据,在非叶子节点也保存数据.

B+tree:所有数据都存储在叶子节点,非叶子节点不存储数据.且叶子节点间构成了双向链表Mysql用的方法是B+tree.

b+tree的插入必须要保证插入后,叶子节点的数据依然有序。而且不管怎么变化,根节点到叶子节点的深度始终是相同的。

B*tree:也只在叶子节点存储数据并构成双向指针,但在非叶子节点有双向指针

 2.聚簇索引表(索引组织表cluster-index)

在建表时,innodb将表结构数据,存储在一个B+TREE,B+TREE叫聚簇索引(cluster-index).以聚簇索引构建的表叫聚簇索引表,又称索引组织表聚集索引页的叶子节点汇总存放着完整的记录,副主索引页中存放着指向叶子的指针。
聚集索引是通过将表的主键作为键值来构造B+树的,因为innoDB存储引擎是通过主键来构造的,所以这需要每一张表都有主键,如果没有显式的指定主键,那么数据库是自动创建主键,聚集索引不仅仅包含索引的键值,还包含了记录所在其他列的值,聚集索引中的记录是根据键值顺序排列的,但是不是物理排序,而是顺序排序。
说明:

1.根据主键寻址速度很快

2.主键值递增的insert插入效率较好

3.主键值随机insert插入操作效率差

建议:innodb表必须指定主键,最好使用自增数字;

       1.聚簇索引构建规则

1.存在主键的情况下,是用主键来构建聚簇索引.

2.在没有主键的情况下,如果有唯一性非空索引,就用该索引构建.

3.都没有,则开辟一个6字节的隐藏列,用隐藏列构建主键索引.

   2.聚簇索引的特点:

1. MySQL的表结构由聚簇索引来构建,表结构本身就是索引的一部分。

2.通过表的主键来键值来构造B+TREE,因为INNODB存储引擎是一个索引组织表,这意味着每张表都有一个主键,如果没有显示的创建,则innodb会创建一个六个字节的主键,聚簇索引不仅仅包含索引的键值,还包含了记录其他列的信息。

3.聚簇索引是根据键值顺序存放的,然而要特别注意的是这个顺序是指逻辑顺序,而不是物理上的存储顺序。因为如果是物理顺序那么排序开销是不被接受的。

4.聚簇索引的非叶子结点存储的是<键值,地址>对。地址为指向下一层的指针,innoDB存储引擎通过页在表空间中的偏移量来表示。

5.创建表如果指定主键,那么会自动以指定的主键进行查询,互联网业务中,大多数的OLTP业务中,都是根据主键来查询数据,同时查询速度也是非常快的。

   3.行数据库表的两大类(索引组织表和堆表)

索引组织表(聚簇索引表)>MySQL默认表结构:表本身就是一个索引,数据按照主键的顺序来进行组织。
堆表(普通的堆表,数据块构成)—>ORACLE默认表结构(ORACLE也支持索引组织表,但是默认ORACLE的主键会默认创建索引)插入数据是随机的

  4.聚簇索引叶子节点块

1.数据页读取到内存,所以对页的操作,首先是在内存中操作的,那么就造成一个问题,某一时间,内存和硬盘的数据页数据不一样,这是通过事务ACID来可以保证,某一个时间点两者的数据会到达最终一致性.
2.数据页在磁盘或者内存空间中,是一次性开辟的,里面的记录是顺序线性存放的(逻辑上的)
3.叶记录是根据主键顺序排列的,这个顺序是逻辑上的。

  5.数据页定位数据记录的过程

在非叶子节点查找数据到叶子节点后,并无法定位数据,在数据页中有一部分叫做page directory,该部分记录了每个数据目录在数据页中的偏移量,知道偏移量后,进行二分法查找,就可以找到了具体的数据记录.


      6.索引优点与缺点

索引优点:
1.加快数据检索效率;

2.可以创建唯一性约束索引,保证数据库表中每一行数据的唯一性;

3.加速表和表连接效率;

4.在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。

说明:

1.索引可以优化DML操作的查询部分。

2. 索引提供了查询的可控性,全表查询IO不可控。

3. 索引查询一条数据的IO次数由索引的层数决定

索引缺点:

1.索引需要占用更多物理存储空间。

2.当对表中的数据进行增加、删除和修改的时候,索引也要更新维护,降低了数据维护效率

说明:1.尽量在表里不要有冗余索引。2.大数据入库时,可以先干掉索引,插入数据,然后重建索引。

  7.索引分类

逻辑上: Single column indexes单列索引

Combined IndexesMultiple-Column Indexes 多列索引

Unique 唯一索引     NonUnique 非唯一索引

物理上: clustered index 聚簇索引       not-clustered index非聚簇索引

复合索引:(建立在多个列上的索引)

    8.哪些情况下建议创建索引:

 · 经常需要搜索的列             · 作为主键的列,有唯一约束索引

· 经常用在表连接的列  · 经常需要排序的列    · 经常使用在WHERE子句中的列

 

3.助索引

辅助索引又称二级索引或非聚簇索引.

    1.辅助索引存放的信息

辅助索引也是B+tree,叶子节点存放的是索引列和主键值,不存放其他列信息.若无主键,则存放的是索引列和该表聚簇索引的虚拟主键值.辅助索引是根据索引列的值排序.

    2.聚簇索引和辅助索引的选择

1. 在聚簇索引和辅助索引都存在的时候,优化器倾向于使用聚簇索引,因为聚簇索引可以通过叶子节点找到数据。

2. 通过辅助索引查询记录仅仅只能得到主键值,要查询完整的记录,还需要通过一次聚簇索引查询。(回表)

3. 仅仅当主键值发生改变的时候,需要更新辅助索引。(问题:索引列改变了难道不更新?)

4. 聚簇索引通常比辅助索引的高度要高(辅助索引不保存所有记录,更小,高度更低)。

 

4.索引覆盖、回表与复合索引

           1.覆盖索引

覆盖索引:只需通过辅助索引就可以返回数据。
一个查询语句的执行只需要从辅助索引中就可以得到查询记录,而不需要查询聚集索引中的记录。也可以称之为实现了索引覆盖。特高频SQL,强烈推荐使用覆盖索引,可以非常大的提高查询效率

    2.回表

 指当通过辅助索引查询得到的记录信息不足,需要回表再通过聚簇索引查询信息.

    3.复合索引

复合索引:建立在多个列上的索引..

关于复合索引的使用:遵从最左前缀原则。如当复合索引列有3个时,where条件里是1或者1、2或者1、 2、 3或者1、3时才可用到复合索引.其他查询都不会用到复合索引

         4.mysql的ICP(索引下推)和对where中过滤条件的处理

ICP:Index Condition Pushdown(索引下推)

ICP技术是在MySQL5.6中引入的一种索引优化技术。它能减少在使用二级索引过滤where条件时的回表次数和减少MySQL server层和引擎层的交互次数。在索引组织表中,使用二级索引进行回表的代价相比堆表中是要高一些的。

当关闭ICP,index 仅仅是data access 的一种访问方式,存储引擎通过索引回表获取的数据会传递到MySQL Server层进行where条件过滤。

当打开ICP,如果部分where条件能使用索引中的字段,MySQL Server 会把这部分下推到引擎层,可以利用index过滤的where条件在存储引擎层进行数据过滤,而非将所有通过index access的结果传递到MySQL server层进行where过滤.

优化效果:ICP能减少引擎层访问基表的次数和MySQL Server 访问存储引擎的次数,减少io次数,提高查询语句性能.

where中过滤条件的处理,根据索引使用情况分成了三种:index key, index filter, table filter

1. index key----确定查询范围

用于确定SQL查询在索引中的连续范围(起始范围+结束范围)的查询条件,被称之为Index Key。由于一个范围,至少包含一个起始与一个终止,因此Index Key也被拆分为Index First KeyIndex Last Key,分别用于定位索引查找的起始,以及索引查询的终止条件。也就是说根据索引来确定扫描的范围。

2. index filter---索引过滤

在使用 index key 确定了起始范围和介绍范围之后,在此范围之内,还有一些记录不符合where 条件,如果这些条件可以使用索引进行过滤,那么就是index filter。也就是说用索引来进行where条件过滤。

3. table filter---条件过滤

where中的条件不能使用索引进行处理的,只能访问table,进行条件过滤了。也就是说各种各样的 where 条件,在进行处理时,分成了上面三种情况,一种条件会使用索引确定扫描的范围;一种条件可以在索引中进行过滤;一种必须回表进行过滤;所以所谓的 ICP 技术,其实就是 index filter 技术而已。只不过因为MySQL的架构原因,分成了server层和引擎层,才有所谓的“下推”的说法。所以ICP其实就是实现了index filter技术,将原来的在server层进行的table filter中可以进行index filter的部分,在引擎层面使用index filter进行处理,不再需要回表进行table filter

     5.索引添加删除语句

添加聚簇索引: alter table t1 add primary key (id);   ---设置id为主键

添加辅助索引:  alter table t1 add index idx_name (name); ---索引名为idx_name

删除索引:  drop index in_a on t1;

   6.索引扫描说明

在语句前加上explain.查看使用哪个索引.key字段的值为使用的索引名,rows字段的值为查询过程中扫描到的数据的行数.最后的Extra若是Using index,则说明是走覆盖索引.当查询一条或几条数据,使用了聚簇索引.keyprimary.

当查询字段是辅助索引列时,走辅助索引.这种不是通过覆盖索引,故是先通过辅助索引再回表,通过聚簇索引查找数据. key显示为辅助索引名称.Extra显示为null.

覆盖索引:Using-index只需通过辅助索引就达到结果.没有通过聚簇索引,故是覆盖索引,key为辅助索引名称,Extra显示为Using index.

   7.唯一索引说明:

 唯一(具有唯一约束的索引,唯一索引):唯一:不能有相同数据

alter table t add unique idx_t1(name).

添加唯一索引时,若该列值有重复,则不能添加.添加成功后,则该列有了唯一约束.

  8.索引的可选择性

索引选择性越高,索引的价值越高 索引可选择性的计算: show index from t1;

后会有一行Cardinality,是不重复记录的预估值(对列去重)。

使用Cardinality/rows就可以得到可选择率,越接近1,索引越高效,其值介于(0,1]

举例:

1. 字段‘gender’,可能有‘男’,‘女’,‘其他’三个值,索引的选择性为 3/1000 = 0.003

2. 字段id,每条记录都不同,索引选择性为1000/1000 = 1

那么查询id123456gender为‘女’的记录时应该使用哪个索引?

显然应该使用id字段上的索引,只要定位到这条索引记录,就可以立刻确定是否存在这条记录,然后再验证性别是否为‘女’,而使用‘gender’字段上的索引,可能需要遍历多条记录,对比id后才能确定是否存在这条记录. 再举一个极端的情况:如果上述表中所有记录的‘gender’字段都为‘女’,那么索引的选择性为1/1000 = 0.001,这时使用‘gender’字段上的索引和全表扫描没啥两样

 

 

转载于:https://www.cnblogs.com/lbg-database/p/10109937.html

你可能感兴趣的:(mysql之索引组织表)