您的位置:首页 > 数据库 > MySQL

mysql索引知识笔记

2017-04-23 14:23 211 查看
索引是帮助Mysql高效获取数据的一种方式,是一种数据结构

目前大部分索引系统用到了B-tree和B+tree数据结构

m阶B-tree的几条特性:

1: 除根结点以外的其他分支结点至少有m/2个子树,根结点最少有两个子子树,最多有m个子树,关键字比指针个数少一。

2:所有叶子结点都在同一层上,每个叶子结点至少包含一个key和两个指针,最多包含m-1个key和m个指针,叶结点的指针均为NULL。

B+tree与B-tree的不同的几条特性:

1.非叶子结点的子树指针与关键字个数相同;

2.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);

3.为所有叶子结点增加一个链指针;

4.所有关键字都在叶子结点出现;

一般在数据库系统或文件系统中使用的B+Tree结构都在经典B+Tree的基础上进行了优化,增加了顺序访问指针。

查找一个范围的数据,只要找到一个数据,就可以根据顺序访问指针找到所有数据,提高了效率。

Mysql主要有两种索引存储引擎:Myisam和innodb

Myisam是用b+tree作为索引结构的,索引文件存储的是数据记录的物理地址,数据文件和索引文件是分离的,是非聚集的,和innodb这点不一样,innodb的叶结点包含了完整的数据记录信息,这种索引叫做聚焦索引。

因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

聚集索引和非聚集索引是一种数据存储方式,不是单独的一种索引类型。

聚集索引的一些优点:

1.可以把相关数据放到一起,

2.数据访问更快,因为数据和索引放到一起,与非聚集索引相比少一部查找操作。

缺点:

1. 插入速度严重依赖于插入顺序,按照主键的顺序插入是加载数据到innodb表中速度最快的方式,但如果不是按照主键顺序加载数据,那么在加载完成后最好使用optimize table命令重新组织一下表。

2. 更新聚集索引列的代价很高,因为会强制innodb将每个被更新的行移动到新的位置。

在innodb表中按主键顺序插入行,如果正在使用Innodb表并且没有什么数据需要聚集,那么可以定义一个代理键作为主键,这种主键的数据应该和应用无关,最简单的方法是使用auto_increment自增列,这样可以保证数据行是按顺序插入的,对于根据主键做关联操作的性能也会更好。

  不要使用UUID来作为聚集索引,否则性能会很糟糕,因为它使得聚集索引的插入变得完全随机,使得数据没有任何聚集特性。因为UUID作为主键插入行不仅花费的时间更长,而且索引也更大,这一方面是因为主键字段变长了,另外一方面毫无疑问是由于页分裂导致时间变长和碎片导致的索引变大。因为主键的值是顺序的,所以Innodb把每一条记录都存储在上一条记录的后面,当达到页的最大填充因子时。

  在UUID主键下,因为新插入行的主键值不一定比前面的大,所以innodb无法简单地总是把新行插入到索引的最后,而是需要为新的行寻找合适的位置,通常是已有数据的中间位置,并且分配新的空间,这会增加很多额外的工作,并导致数据分布不够优化,下面是使用UUID作为主键的一些缺点:

A:写入的目标页可能已经刷到磁盘上并从缓存中移除,或者是还没有被加载到缓存中,innodb在插入前不得不先找到并从磁盘读取目标页到内存中,这将导致大量的随机IO

B:因为写入是乱序的,innodb不得不频繁地做页分裂操作,以便为新的行分配空间,页分裂会导致移动大量数据。

C:由于频繁的页分裂,页会变得稀疏并被不规则地填充,所以最终数据会有碎片

注:顺序的主键什么时候会造成更坏的结果?

  对于高并发工作负载,在Innodb中按主键顺序插入可能会造成明显的争用,主键的上界会称为热点,因为所有的插入都发生在这里,所以并发插入可能导致间隙锁争用,另一个热点可能是auto_increment锁机制,如果遇到这个问题,则可能需要重新设计表或者应用,或者更改innodb_autoinc_lock_mode配置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: