mysql索引结构原理、性能分析与优化(一)

2015-01-21 11:32:26 · 作者: · 浏览: 28

第一部分:基础知识

索引

官方介绍索引是帮助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结构视图 B-tree结构视图

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

Ki表示关键字值,上图中,k1

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

MyISAM索引结构

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

MyISAM索引用的B+ tree

结构讲解:上图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列则系统自动创建一个。

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

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

在已有主键索引,避免数据冗余,同时在修改数据的时候只需修改辅助索引值。但辅助索引查找数据事要检索两次,先找到相应的主键索引