(一)关于存储引擎

创建合适的索引是SQL性能调优中最重要的技术之一。在学习创建索引之前,要先了解MySql的架构细节,包括在硬盘上面如何组织的,索引和内存用法和操作方式,以及存储引擎的差异如何影响到索引的选择。

MySQL有很多种衍生版本,这些衍生版本支持更多不同种类的存储引擎。本文主要讨论三种MySQL引擎。

MyISAM 一种非事务性的存储引擎,是MySQL 5.5之前版本默认的存储引擎。

InnoDB  最流行的事务性存储引擎,从5.5版开始成为MySQL默认的引擎。

Memory 基于内存的,非事务性的以及非持久性的存储引擎。

注意:

从5.5版本开始,MySQL表的默认存储引擎从MyISAM换成InnoDB,将会使用户安装那些依赖默认设置或者专门为MyISAM编写的软件包时带来很大的影响。

(二)MySQL索引类型

MySQL支持在所有关系数据库表中创建主键、唯一键、不唯一的非主码索引等多种类型的索引。此外MySQL还支持纯文本和空间索引类型。

MySQL内置的存储引擎对各种索引技术有不同的实现方式,包括:B-树,B+树,R-树以及散列类型。

索引数据结构理论:

1.B-树

B-树中有两种节点类型:索引节点和叶子节点。叶子节点是用来存储数据的,而索引节点则用来告诉用户存储在叶子节点中的数据顺序,并帮助用户找到相应的数据。

B-树的搜索,从根节点开始,对节点内的关键字有序进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子节点,重复。直到所对应的儿子指针为空,或已经是叶子节点。

B-树是一种多路搜索树:

(1). 定义任意非叶子节点最多有M个儿子,且M>2;

(2). 根节点的儿子数为[2,M];

(3). 除根节点以外的非叶子节点的儿子数为[M/2,M];

(4). 每个节点存放至少M/2-1(取上整)和至多M-1个关键字;

(5). 非叶子节点的关键字个数=指向儿子节点的指针的个数-1;

(6). 非叶子节点的关键字:k[i]<k[i+1];

(7). 非叶子节点的指针:p[1],p[2],·····,p[M];其中p[1]指向的关键字小于k[1]的子树,p[M]指向的关键字大于K[m-1]的子树;

(8). 所有的叶子节点位于同一层;

2.B+树

B+树数据结构是B-树实现的增强版本。尽管B+树支持B-树索引的所有特性,它们之间最显著的不同点在于B+树中底层数据是根据被提及的索引列进行排序的。B+树还通过叶子节点之间的附加引用来优化扫描性能。

B+搜索和B-搜索不同,区别是B+树只有达到叶子节点才命中(B-树可以在非叶子节点命中),其性能等价于关键字全集做一次二分搜索。

B+树的特性:

(1)所有关键字都出现在叶子节点的链表中,叶子节点相当于存储数据的数据层。

(2)不可能在非叶子节点上命中。

(3)非叶子节点相当于是叶子节点的索引,叶子节点相当于数据层。

3.散列

散列表数据结构是一种很简单的概念,它将一种算法应用到给定值中以在底层数据存储系统中返回一个唯一的指针或位置。散列表的优点是始终以线性时间复杂度找到需要读取的行的位置,而不像B-树那样需要横跨多层节点来确定位置。

4.通信R-树

R-树数据结构支持基于数据类型对几何数据进行管理。目前只有MyISAM使用R-树实现支持空间索引,使用空间索引也有很多限制,比如只支持唯一的NOT NULL列等。

5.全文本

全文本结构也是一种MySQL采用的基本数据结构。这种数据结构目前只有当前版本MySQL中的MyISAM存储引擎支持。5.6版本将要在InnoDB存储引擎中加入全文本功能。全文本索引在大型系统中并没有什么实用的价值,因为大规模系统有很多专门的文件检索产品。所以不用在介绍。

MySQL实现

对B-树,B+树和散列等数据结构的基本概念有了一些了解之后,我们就可以开始讨论MySQL通过支持它们的存储引擎如何实现不同的算法。同时每种实现也对磁盘和内存使用情况有不同的影响,这一点在大型数据库系统中是非常重要的考虑因素。

1.MyISAM的B-树

   MyISAM存储引擎使用B-树数据结构来实现主码索引、唯一索引以及非主码索引。在MyISAM实现数据目录和数据库模式子目录中,用户可以找到和每个MySQL表对应的.MYD和.MYI文件。数据库表上定义的索引信息就存储在MYI文件中,该文件的块大小是1024字节。这个大小是可以通过myisam-block-size系统变量分配。

$  ls -1h /var/lib/mysql/book/source_words.MY*

-rw-rw---- 1 mysql mysql  9.2M 2015-05-07 19:08

source_words.MYD

-rw-rw---- 1 mysql mysql  7.8M 2015-05-07 19:08

source_words.MYI

这些文件结构的内部格式可以从MySQL免费源代码中找到,也可以查看MySQL内部手册。

在MyISAM中,非主码索引的B-树结构存储索引值和一个指向主码数据的指针,这是MyISAM和InnoDB的一个显著区别。这一点导致了两个存储引擎的索引的不同工作方式。

MyISAM索引是在内存的一个公共缓存中管理的,这个缓存的大小可以通过key_buffer_size或者其他命名键缓存来定义。这是根据统计和规划的表索引的大小来设定缓存大小时主要的考虑因素。

2. InnoDB的B+树聚簇主码

InnoDB存储引擎在它的主码索引(也被称为聚簇主码)中使用了B+树,这种结构把所有数据都和对应的主码组织在一起,并且在叶子节点这一层上添加额外的向前和向后的指针,这样就可以更方便地进行范围扫描。

在文件系统层面,所有InnoDB数据和索引信息都默认在公共InnoDB表空间中管理,否则管理员就通过innodb_data_file_path这个变量指定文件路径。这是一个叫ibdatal文件。

由于InnoDB用聚簇主码存储数据,底层信息占用的磁盘空间的大小很大程度上取决于页面的填充因子。对于按序排列的主码,InnoDB会用16K页面的15/16作为填充因子。对于不是按序排列的主码,默认情况下InnoDB会插入初始数据的时候为每一个页面分配50%作为填充因子。

在改索引的实现方式中B+树的叶子节点上是data就是数据本身,key为主键,如果是一般索引的话,data便会指向对应的主索引。在B+树的每一个叶子节点上面增加一个指向相邻叶子节点的指针,就形成了带有顺序访问指针的B+树。其目的是提高区间访问的性能。

3.InnoDB的B-树非主码

InnoDB中的非主码索引使用了B-树数据结构,但InnoDB中的B-树结构实现和MyISAM中并不一样。在InnoDB中,非主码索引存储的是主码的实际值。而MyISAM中,非主码索引存储的包含主码值的数据指针。这一点很重要。首先,当定义很大的主码的时候,InnoDB的非主码索引可能回更大,随着非主码索引数量的增加,索引之间大小差别可能会变得很大。另一个不同点在于非主码索引当前可以包含主键的值,并且可以不是索引必须有的部分。

4.内存散列索引

在默认MySQL的引擎索引中,只有MEMORY引擎支持散列数据结构,散列结构的强度可以表示为直接键查找的简单性,散列索引的相似度模式匹配查询比直接查询慢。也可以为MEMORY引擎指定一个B-树索引实现。

5.内存B-树索引

对于大型MEMORY表来说,使用散列索引进行索引范围搜索的效率很低,B-树索引在执行直接键查询时确实比使用默认的散列索引快。根据B-树的不同深度,B-树索引在个别操作中的确可能比散列算法快。

6.InnoDB内部散列索引

 InnoDB存储引擎在聚簇B+树索引中存储主码:但在InnoDB内部还是使用内存中的散列表来更高效地进行主码查询。这个机制有InnoDB存储引擎来管理,用户只能通过innodb_adaptive_hash_index配置项来选择是否启用这个唯一的配置选项。

转自微信公众号:民工哥技术之路

深入了解MySQL存储索引的更多相关文章

  1. MySQL存储索引InnoDB数据结构为什么使用B+树,而不是其他树呢?

    InnoDB的一棵B+树可以存放多少行数据? 答案:约2千万 为什么是这么多? 因为这是可以算出来的,要搞清楚这个问题,先从InnoDB索引数据结构.数据组织方式说起. 计算机在存储数据的时候,有最小 ...

  2. mysql存储引擎和索引

    正确的创建合适的索引,是提升数据库查询性能的基础. 第一章 mysql之索引 索引的定义:索引是为了加速对表中数据行的检索而创建的一种分散存储的数据结构. 我们为什么要使用索引: a.极大的减少存储引 ...

  3. MySQL存储引擎与索引

    引言: MySQL存储引擎主要分为 InnoDB 存储引擎与 MyISAM 存储引擎.都采用B+数的存储结构. 应用场景: InnoDB适合:(1)可靠性要求比较高,要求事务:(2)大量 insert ...

  4. 为什么用B+树做索引&MySQL存储引擎简介

    索引的数据结构 为什么不是二叉树,红黑树什么的呢? 首先,一般来说,索引本身也很大,不可能全部存在内存中,因此索引往往以索引文件的方式存在磁盘上.然后一般一个结点一个磁盘块,也就是读一个结点要进行一次 ...

  5. 为什么MySQL数据库要用B+树存储索引?

    问题:MySQL中存储索引用到的数据结构是B+树,B+树的查询时间跟树的高度有关,是log(n),如果用hash存储,那么查询时间是O(1).既然hash比B+树更快,为什么mysql用B+树来存储索 ...

  6. 用漫画的形式来讲解为什么MySQL数据库要用B+树存储索引?

    小史是一个应届生,虽然学的是电子专业,但是自己业余时间看了很多互联网与编程方面的书,一心想进BAT互联网公司. 话说两个多月前,小史通过了A厂的一面,两个多月后的今天,小史终于等到了A厂的二面. 简单 ...

  7. MySQL存储引擎MyISAM和InnoDB,索引结构优缺点

    MySQL存储引擎MyISAM和InnoDB底层索引结构 深入理解MySQL索引底层数据结构与算法 (各种索引结构优缺点) Myisam和Innodb索引实现的不同(存储结构) 存储引擎作用于什么对象 ...

  8. Database基础(二):MySQL索引创建与删除、 MySQL存储引擎的配置

    一.MySQL索引创建与删除 目标: 本案例要求熟悉MySQL索引的类型及操作方法,主要练习以下任务: 普通索引.唯一索引.主键索引的创建/删除 自增主键索引的创建/删除 建立员工表yg.工资表gz, ...

  9. mysql总结:索引,存储引擎,大批量数据插入,事务,锁

    mysql总结 索引概述: 索引是高效获取数据的数据结构 索引结构: B+Tree() Hash(不支持范围查询,精准匹配效率极高) 存储引擎: 常见存储引擎: Myisam:5.5之前默认引擎,支持 ...

随机推荐

  1. Selenium自动化测试值环境搭建

    Selenium自动化测试之环境搭建 一.背景介绍 自动化测试近几年在测试领域很火,出去面试要是说不会自动化测试薪资都不好意思往高了要!很多公司做敏捷测试用到自动化,其他一些公司也是跟风,即使用不上自 ...

  2. [微信小程序] js变量名称写活

    function create_variable(num){ var name = "test_"+num; //生成函数名 window[name] = 100; window[ ...

  3. 爬虫实战:汽车之家配置页面 破解伪元素和混淆JS

    本篇介绍如何破解汽车之家配置页面的伪元素和混淆的JS. ** 温馨提示:如需转载本文,请注明内容出处.** 本文链接:https://www.cnblogs.com/grom/p/9242156.ht ...

  4. pycharm多行注释

    选中需要注释的代码 ctrl+/ #首字母大写# test = 'alex'# v = test.capitalize()# print (v)## 字符串的加法# n1 = 'my '# n2 = ...

  5. 在express中HMR(合并express和webpack-dev-server)

    在学习react的时候,经常用create-react-app来创建web应用,然而写到后面总有连自己服务器和数据库的需求,create-react-app创建的是一个webpack-dev-serv ...

  6. MySQL学习【第九篇存储引擎】

    一.存储引擎介绍 1.我们知道mysql程序构成由连接层,sql层,存储引擎层.存储引擎层和磁盘进行交互,由其去取数据,而我们取得数据是表的形式展现出来,谁做的呢?就是存储引擎结构化成表的形式返回给用 ...

  7. 解决docker pull出现 error pulling image configuration: Get https://dseasb33srnrn.cloudfront.net······: net/http: TLS handshake timeout的问题

    [root@MyCentos7 var]# docker pull javaUsing default tag: latestTrying to pull repository docker.io/l ...

  8. React项目的最佳实践

    项目代码 从零开始简书项目 ​ 从我第一次接触vue这个框架已经过了快一年的时间,陪伴我从前端小白到前端工程师,前端时间也是使用了 ts+vue这样的组合写代码,明显感觉vue与ts似乎没有产生比较好 ...

  9. daterangepicker的个性化使用技巧

    由于该模板不自动将时间戳添加到input中去,始终为NaN,所以,自己选取起始时间与截止时间 var startTime =new Date(new Date().toLocaleDateString ...

  10. Python + 百度Api 通过地址关键字获得格式化的地址信息

    由于用户输入是千奇百怪的,除了格式语法不合要求之外的,即便是所谓的合法数据也是五花八门.尤其是地址,所有才由此文. 百度Api注册一个账号,创建一个应用后就会有一个`ak`的参数,就够了. Pytho ...