小白学习mysql之索引初步

导语

索引在数据库中的地位是及其的重要,同时要想彻底的掌握索引并非一件容易的事,须要对数据的查询原理以及计算机操做系统有深入的认识,固然相关的算法和数据结构也是必须的。所以,这篇文章感到了一些压力,不过仍是决定先拿出来总结一下,理一理索引,就当作学习笔记了。算法

索引的重要习性犹如一本字典的拼音检索和部首检索部分,想象一下你买了一本只有正文的字典,那该有多么抓狂。并且在一个软件系统中,一般数据的查询与修改每每占到了10:1的比例,也就是咱们须要将大部分的精力投入到数据的查询上,其中不少工做是用来提高查询的速度的,那么在这个过程当中索引就扮演者很是重要的角色。sql

索引的实质

若是说一本字典的正文内容的实质是纸张的话,那么它前面按照拼音或者部首检索的索引的实质是什么呢!固然也是纸张了,可能有人以为是废话,当咱们同时类比到索引上就能够知道,一个数据表的实质是数据文件(即文件),那么索引的实质也固然是文件了,Mysql的InnoDB的数据表中的索引就是表空间的一部分。所以,初学者能够把索引彻底想象成为一本字典,一本字典就是一个数据表,正文部分呢,就是这个数据表的详细内容,按照拼音和部首的检索都是索引。
当咱们经过索引查找一条数据项的时候就犹如经过拼音索引查找某一个字,当在索引中查找到那个字的时候,会根据右边对应的页码找到那个字的解释,一样,MySQL的索引工做原理也是如此,每一个索引项都有一个建索引列的关键字和一个指向该数据项的指针(相似字典中的页码),当咱们查找到那个目标关键字时,根据指针即可以直接定位到数据表中该关键字的位置。数据库

但现实中的真是数据表并不像字典那样,内容都是严格按照拼音序列排列的,由于有不少不肯定的新内容要插入或者要进行其余操做,因此字典只是一种特殊的数据表,并不能把全部的数据表都拿来和字典比,这里用字典来类比只是为了对索引的实质有一个立体的认识。缓存

索引是如何实现快速查找的

假设A公司有1024名员工(员工编号1-1024),早上的出勤人数为1023次,如今想知道员工编号为8的小明是否出勤,如何经过早上的签到表快速的查询小明是否出勤呢!在没有索引的状况下,一般的作法是从第一条记录逐个向后查找,若是小明最后一个来或者没有来,那么就须要查找1023次,效率为O(N)。也许会以为1023次查找对如今的计算机根本不算什么,可是对于不少系统动辄都是上千万的数据记录,你能够想象查找的时间,好比你用15分钟终于经过了qq的身份校验登录上了qq是一种怎么样的体验。所以,索引就呼之欲出了,咱们如何经过索引来提升一个数量级的查找效率,这个时候就须要对这1024条数据作些什么了,在每条记录插入的时候,能够根据每条记录的员工编号和存储该记录的地址(指针)创建一个二叉查找树,这样1023条记录即可以经过10次查找即可查到,查找效率足足提升了100倍。数据结构

一样,为了效率的提高,也付出了一些代价,由于创建二叉查找树须要额外的存储空间,同时每次插入数据的时候须要对二叉查找树进行维护,减缓了数据的更新速度。但综合来考虑,通常认为这样作是值得的。学习

固然在MySQL中,不是采用的二叉树查找树来完成索引的存储的,上面举得例子只是为了说明索引的工做过程,但其思想是相同的。MySQL中没有特殊说明的话,通常说的索引指的就是B-Tree索引,采用B-Tree这种数据结构是综合了计算机操做系统以及组成而综合考虑的。其核心思想主要是减小磁盘的IO次数,提升查询速度。操作系统

如何理解聚簇索引

你只需记住它的名字叫聚簇索引,它不一样于其余普通的索引!聚簇索引不只仅是一种索引,更是一种存储方式,InnoDB中将B-Tree索引和数据行存储在一个数据结构中,意味着什么呢?这意味着数据行即索引,索引即数据行,它们是在一块儿,在一块儿,在一块儿的。指针

接着经过来创建字典的例子来理解聚簇索引和其余普通索引的区别,如今要创建一本中华字典,这个时候字典是空的,要咱们造一本字典出来,首先咱们要完成字典的正文,咱们按照汉语拼音的顺序去组织字典的正文,第一个是“安 an ”,放在一个位置,同时后面附加上注释(这里,“an”就至关于聚簇索引的关键字,然后面的注释就是数据行,它们存在一块儿),第二个是“王 wang”字,经过和“安 an”字比较,拼音顺序靠后,因此放第二个。注意这里的放是指存储在磁盘中的位置,能够理解为存储顺序。第三个字是“小 xiao”字,经过拼音顺序,须要将第三个字存在第一个字“安”后面,那“王”字已经占了磁盘页面的位置,因此它须要向后面移动,若是移出该列,就致使了也分裂,因此能够看到汇集索引的更新代价真的很大,那为何还要这样作呢?聚簇索引带来了那些好处?code

......,假设按照上面方法已经创建好了字典的正文内容,这个时候就可让咱们体会一下聚簇索引的好处了,假如你要找“安 an”字,根据拼音序列,你必定知道它必定在前几个页面,因此直接能够翻到前面,同时你也能够找到拼音“an”所对应的全部的汉字,这就是聚簇索引带来的好处,同时聚簇索引是和数据行放在一块儿的,你不须要在根据索引里的指针找到对应的数据行,而后翻页找到(翻页就至关于磁盘IO),这些都是效率的提高。然而,上面也看到了聚簇索引的负面影响好比插入的时候,所以它就像通常利剑,用的合适效率提高,用的糟糕也会带来很大的很差影响。索引

是时候区别一下非聚聚索引了,这个时候咱们又按照部首创建了一个索引,那么按照部首创建的索引就是非聚簇索引,它单独的存在在字典的前几个页面,并且同一个部首的字所对应的页码也是没有顺序的,若是咱们要山字旁所对应的全部汉字,那就要取不少个页面的值,致使不少随机IO产生,同时不能很好利用计算机存储系统的缓存系统,所以效率远没有聚簇索引高。

InnoDB中聚簇索引产生的原则:

  • 当有主键时,主键为聚簇索引
  • 当没有主键时,引擎会选择一个惟一非空列来做为聚簇索引
  • 若是没有以上两种状况的列,引擎会隐式的定义一个主键做为聚簇索引

最后,经过创建一个数据表来感觉聚簇索引,首先创建有一个没有主键也没有惟一非空列索引的数据表,即聚簇索引是系统隐式生成这种状况。这种状况,通常就是按数据插入的前后顺序进行排列。

CREATE TABLE user_log (
    user_id INT NOT NULL,
    place VARCHAR(20) NOT  NULL DEFAULT '',
    login_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP 

) DEFAULT CHARSET utf8;

接下来插入三条数据:

> INSERT INTO user_log(user_id,place)
    VALUES('1','中国');
> INSERT INTO user_log(user_id,place)
    VALUES('2','中国');
> INSERT INTO user_log(user_id,place)
    VALUES('1','美国');

而后,选择全部列(即按照存储顺序查看数据列),果真如咱们猜测,是按照插入顺序存储的:

>   SELECT * FROM user_log;

user_id place   login_time
1   中国  2015-11-20 10:32:41
2   中国  2015-11-20 10:33:18
1   美国  2015-11-20 10:33:18

接下来,咱们添加一个惟一的索引(ID+login_time),此时 系统引擎应该将此索引做为聚簇索引,所以咱们再次插入新的数据的时候是按照ID聚簇存储的,就是说ID相同的会存储在一块儿,存储在同一个页面,甚至连续的几个页面。
下面首先添加这个惟一索引 并接着添加三条新的记录:

> ALTER TABLE user_log ADD UNIQUE KEY U_USER_LOG_ID_LOGIN_TIME(user_id,login_time);

> INSERT INTO user_log(user_id,place)
    VALUES('1','法国');
> INSERT INTO user_log(user_id,place)
    VALUES('2','日本');
> INSERT INTO user_log(user_id,place)
    VALUES('1','韩国');

而后接着查看数据的存储状况:

>   SELECT * FROM user_log;

user_id place   login_time
1   中国  2015-11-20 10:32:41
1   美国  2015-11-20 10:33:18
1   法国  2015-11-20 10:48:00
2   中国  2015-11-20 10:33:18
2   日本  2015-11-20 10:48:00

这样以来,若是咱们要获取某一个用户的登录状况,就能够很是的方便,由于该用户的全部登录记录是按照ID汇集的存储在一块儿的,这样主存缓存一个页面的数据可能就OK了,若是是非汇集存储的,假如某个id的数据分散在100个页面,那么主存就要缓存这100个页面,效率可想而知。

总结

这篇文中一开始的构想是想从计算机操做系统的存储系统和B-Tree入手写的,结果写着写着发现,有点不太现实,一来文章长度可能增长几倍,二来可能本身都写晕了,既然是小白篇嘛,就先来个综述吧!总之索引是很是强大并且有意思的,然而当数据量达到必定量时,感受索引也是有点乏力,可是尽可能用好每个索引是很是有必要并且是一种态度。

相关文章
相关标签/搜索