码迷,mamicode.com
首页 > 数据库 > 详细

[转]mysql索引结构原理、性能分析与优化

时间:2016-01-06 21:48:03      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:

第一部分:基础知识

 

索引

 

官方介绍索引是帮助MySQL高效获取数据的数据结构。笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页查阅找出需要的资料。

唯一索引(unique index)

 

强调唯一,就是索引值必须唯一。

创建索引:

create unique index 索引名 on 表名(列名);

alter table 表名 add unique index 索引名 (列名);

删除索引:

drop index 索引名 on 表名;

alter table 表名 drop index 索引名;

主键

 

主键就是唯一索引的一种,主键要求建表时指定,一般用auto_increment列,关键字是primary key

主键创建:

creat table test2 (id int not null primary key auto_increment);

全文索引

 

InnoDB不支持,MyISAM支持性能比较好,一般在 CHAR、VARCHAR 或 TEXT 列上创建。

Create table 表名( 

    id int not null primary key anto_increment,

    title varchar(100),FULLTEXT(title)

)type=MyISAM;

单列索引与多列索引

 

索引可以是单列索引也可以是多列索引(也叫复合索引)。按照上面形式创建出来的索引是单列索引,现在先看看创建多列索引:

create table test3 (

    id int not null primary key auto_increment,

    uname char(8) not null default ‘‘,

    password char(12) not null,

    INDEX(uname,password)

)type=MyISAM;

注意:INDEX(a, b, c)可以当做a或(a, b)的索引来使用,但不能当作b、c或(b,c)的索引来使用。这是一个最左前缀的 优化方法,在后面会有详细的介绍,你只要知道有这样两个概念。

聚簇索引

 

一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序。 聚簇索引确定表中数据的物理顺序。Mysql中MyISAM 表是没有聚簇索引的,innodb有(主键就是聚簇索引),聚簇索引在下面介绍innodb结构的时有详细介绍。

查看表的索引

 

通过命令:Show index from 表名 如:

mysql> show index from test3;  

+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+----+

| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | 

Packed | Null | Index_type | Comment |  

+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+----+

| test3 |          0 | PRIMARY  |        1  |    id          |     A     |   0          |     NULL | 

NULL   |     | BTREE      |         |  

+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+

Table:表名

Key_name:什么类型索引(这里是主键)

Column_name:索引列的字段名

Cardinality:索引基数,很关键的一个参数,平均数值组=索引基数/表总数据行,平均数值组越接近1就越有可能利用索引

Index_type:如果索引是全文索引,则是fulltext,这里是b+tree索引,b+tree也是这篇文章研究的重点之一

第二部分:MyISAM和INNODB索引结构

 

简单介绍B-tree B+ tree树

 

B-tree结构视图 

一棵m阶的B-tree树,则有以下性质

Ki表示关键字值,上图中,k1<k2<…<ki<k0<Kn(可以看出,一个节点的左子节点关键字值<该关键字值<右子节点关键字值)

Pi表示指向子节点的指针,左指针指向左子节点,右指针指向右子节点。即是:p1[指向值]<k1<p2[指向值]<k2……

所有关键字必须唯一值(这也是创建MyISAM 和innodb表必须要主键的原因),每个节点包含一个说明该节点多少个关键字,如上图第二行的i和n

节点:

每个节点最可以有m个子节点。

根节点若非叶子节点,至少2个子节点,最多m个子节点

每个非根,非叶子节点至少[m/2]子节点或叫子树([]表示向上取整),最多m个子节点

关键字:

根节点的关键字个数1~m-1

非根非叶子节点的关键字个数[m/2]-1~m-1,如m=3,则该类节点关键字个数:2-1~2

关键字数k和指向子节点个数指针p的关系:

k+1=p ,注意根据储存数据的具体需求,左右指针为空时要有标志位表示没有 B+tree结构示意图如下: 

B+树是B-树的变体,也是一种多路搜索树: * 非叶子结点的子树指针与关键字个数相同 * 为所有叶子结点增加一个链指针(红点标志的箭头)

MyISAM索引结构

 

MyISAM索引用的B+ tree来储存数据,MyISAM索引的指针指向的是键值的地址,地址存储的是数据,如下图:

 

结构讲解:上图3阶树,主键是Col2,Col值就是改行数据保存的物理地址,其中红色部分是说明标注。

1标注部分也许会迷惑,前面不是说关键字15右指针的指向键值要大于15,怎么下面还有15关键字?因为B+tree的所有叶子节点 包含所有关键字且是按照升序排列(主键索引唯一,辅助索引可以不唯一),所以等于关键字的数据值在右子树

2标注是相应关键字存储对应数据的物理地址,注意这也是之后和InnoDB索引不同的地方之一

2标注也是一个所说MyISAM表的索引和数据是分离的,索引保存在”表名.MYI”文件内,而数据保存在“表名.MYD”文件内,2标注 的物理地址就是“表名.MYD”文件内相应数据的物理地址。(InnoDB表的索引文件和数据文件在一起)

辅助索引和主键索引没什么大的区别,辅助索引的索引值是可以重复的(但InnoDB辅助索引和主键索引有很明显的区别,这里 先提醒注意一下)

Innode索引结构

 

(1)首先有一个表,内容和主键索引结构如下两图:

Col1

Col2

Col3

1

15

phpben

2

20

mhycoe

3

23

phpyu

4

25

bearpa

5

40

phpgoo

6

45

phphao

7

48

phpxue

…… 

 

结构上:由上图可以看出InnoDB的索引结构很MyISAM的有很明显的区别

MyISAM表的索引和数据是分开的,用指针指向数据的物理地址,而InnoDB表中索引和数据是储存在一起。看红框1可看出一行 数据都保存了。

还有一个上图多了三行的隐藏数据列(虚线表),这是因为MyISAM不支持事务,InnoDB处理事务在性能上并发控制上比较好, 看图中的红框2中的DB_TRX_ID是事务ID,自动增长;db_roll_ptr是回滚指针,用于事务出错时数据回滚恢复;db_row_id 是记录行号,这个值其实在主键索引中就是主键值,这里标出重复是为了容易介绍,还有的是若不是主键索引(辅助索引), db_row_id会找表中unique的列作为值,若没有unique列则系统自动创建一个。关于InnoDB跟多事务MVCC点 此: http://www.phpben.com/?post=72

(2)加入上表中Col1是主键(下图标错),而Col2是辅助索引,则相应的辅助索引结构图: 

可以看出InnoDB辅助索引并没有保存相应的所有列数据,而是保存了主键的键值(图中1、2、3….)这样做利弊也是很明显:

在已有主键索引,避免数据冗余,同时在修改数据的时候只需修改辅助索引值。

但辅助索引查找数据事要检索两次,先找到相应的主键索引值然后在去检索主键索引找到对应的数据。这也是网上很多 mysql性能优化时提到的“主键尽可能简短”的原因,主键越长辅助索引也就越大,当然主键索引也越大。

MyISAM索引与InnoDB索引相比较

 

MyISAM支持全文索引(FULLTEXT)、压缩索引,InnoDB不支持

InnoDB支持事务,MyISAM不支持

MyISAM顺序储存数据,索引叶子节点保存对应数据行地址,辅助索引很主键索引相差无几;InnoDB主键节点同时保存数据行,其他辅助索引保存的是主键索引的值

MyISAM键值分离,索引载入内存(key_buffer_size),数据缓存依赖操作系统;InnoDB键值一起保存,索引与数据一起载入InnoDB缓冲池

MyISAM主键(唯一)索引按升序来存储存储,InnoD

[转]mysql索引结构原理、性能分析与优化

标签:

原文地址:http://www.cnblogs.com/duanxz/p/5106777.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!