Mysql 磁盘存储和其他索引
文章目录
磁盘存储
我们都知道,mysql是将数据存储在磁盘中的,一般就放在mysql目录下的data文件夹下面。
但我们要说的是索引的磁盘存储
首先复习下索引的查找和增删过程
- 进行查找操作时,首先在根节点进行二分查找,找到一个 key 所在的指针,然后递归地在指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出 key 所对应的 data。
- 插入删除操作会破坏平衡树的平衡性,因此在进行插入删除操作之后,需要对树进行分裂、合并、旋转等操作来维护平衡性。
接下来了解一下B+Tree索引磁盘存储的原理
- 首先,操作系统一般将内存和磁盘分割成固定大小的块,每一块称为一页,内存与磁盘以页为单位交换数据。
- 数据库系统将索引的一个节点的大小设置为页的大小,使得一次 I/O 就能完全载入一个节点。(默认为16k)
- 如果数据不在同一个磁盘块上,那么通常需要移动制动手臂进行寻道,而制动手臂因为其物理结构导致了移动效率低下,从而增加磁盘数据读取时间。(这也是为什么聚簇结构比非聚簇结构查询更快的原因)
- B+树相比于其他的二叉树而言(如红黑树)有着更低的树高(深度),进行寻道的次数与树高成正比,在同一个磁盘块上进行访问只需要很短的磁盘旋转时间,所以 B+ 树更适合磁盘数据的读取。
- 为了减少磁盘 I/O 操作,磁盘往往不是严格按需读取,而是每次都会预读。预读过程中,磁盘进行顺序读取,顺序读取不需要进行磁盘寻道,并且只需要很短的磁盘旋转时间,速度会非常快。并且可以利用预读特性,相邻的节点也能够被预先载入
其他索引
我们对于B+Tree索引已经比较熟悉了,接下来了解下其他结构的索引
哈希索引
底层结构是hash表,上一节有了解过它的结构特性,所以不在重复
它有着以下特点
- 等值查找非常快,为 O(1)
- 失去了有序性,无法进行排序和分组,也不支持范围查找和部分查找
可以看到哈希索引有着一个非常优秀的特点,等值查询极其快。
所以为了让B+Tree索引也用上这个特点,InnoDB 存储引擎有一个特殊的功能叫自适应哈希索引,当某个索引值被使用的非常频繁时,会在 B+Tree 索引之上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,比如快速的哈希查找
全文索引
什么是全文索引(fulltext)
如果希望通过关键字的匹配来进行查询过滤,那么就需要基于相似度的查询,而不是原来的精确数值比较。全文索引就是为这种场景设计的
全文索引和like + % 有什么区别
like + % 在文本比较少时是合适的,但是对于大量的文本数据检索,是不可想象的。全文索引在大量的数据面前,能比 like + % 快 N 倍,速度不是一个数量级,但是全文索引可能存在精度问题。
支持的引擎和版本
- MySQL 5.6 以前的版本,只有 MyISAM 存储引擎支持全文索引;
- MySQL 5.6 及以后的版本,MyISAM 和 InnoDB 存储引擎均支持全文索引;
- 只有字段的数据类型为 char、varchar、text 及其系列才可以建全文索引。
- 对于中文,可以使用 MySQL 5.7.6 之后的版本,或者 Sphinx、Lucene 等第三方的插件;
使用方式
//创建表时创建全文索引
create table fulltext_test (
id int(11) NOT NULL AUTO_INCREMENT,
content text NOT NULL,
tag varchar(255),
PRIMARY KEY (id),
FULLTEXT KEY content_tag_fulltext(content,tag) // 创建联合全文索引列
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
//在已存在的表上创建全文索引
create fulltext index content_tag_fulltext on fulltext_test(content,tag);
//通过 SQL 语句 ALTER TABLE 创建全文索引
alter table fulltext_test add fulltext index content_tag_fulltext(content,tag);
//删除
//直接使用 DROP INDEX 删除全文索引
drop index content_tag_fulltext on fulltext_test;
//通过 SQL 语句 ALTER TABLE 删除全文索引
alter table fulltext_test drop index content_tag_fulltext;
//使用方式
select * from fulltext_test where match(content,tag) against('xxx xxx');
最小搜索长度和全文解析器ngram
MySQL 中的全文索引,有两个变量,最小搜索长度和最大搜索长度,对于长度小于最小搜索长度和大于最大搜索长度的词语,都不会被索引。通俗点就是说,想对一个词语使用全文索引搜索,那么这个词语的长度必须在以上两个变量的区间内。
//查看方式
show variables like '%ft%';
//结果
// MyISAM
ft_min_word_len = 4;
ft_max_word_len = 84;
// InnoDB
innodb_ft_min_token_size = 3;
innodb_ft_max_token_size = 84;
ngram就是一段文字里面连续的n个字的序列。ngram全文解析器能够对文本进行分词,每个单词是连续的n个字的序列。
MySQL 中使用全局变量 ngram_token_size 来配置 ngram 中 n 的大小,它的取值范围是1到10,默认值是 2。通常ngram_token_size设置为要查询的单词的最小字数。如果需要搜索单字,就要把ngram_token_size设置为 1。在默认值是 2 的情况下,搜索单字是得不到任何结果的。因为中文单词最少是两个汉字,推荐使用默认值 2。
//查看方式
show variables like 'ngram_token_size'
修改:
//上述变量都可以修改 但不支持动态修改
//只能更改配置文件或者增加启动参数
//增加启动参数
mysqld --ngram_token_size=2
//更改配置文件
[mysqld]
ngram_token_size=2
两种模式的全文索引
自然语言的全文索引
默认情况下,或者使用 innatural language mode 修饰符时,match() 函数对文本集合执行自然语言搜索,上面的例子都是自然语言的全文索引。
自然语言搜索引擎将计算每一个文档对象和查询的相关度。这里,相关度是基于匹配的关键词的个数,以及关键词在文档中出现的次数。在整个索引中出现次数越少的词语,匹配时的相关度就越高。相反,非常常见的单词将不会被搜索,如果一个词语的在超过 50% 的记录中都出现了,那么自然语言的搜索将不会搜索这类词语。上面提到的,测试表中必须有 4 条以上的记录,就是这个原因。
这个机制也比较好理解,比如说,一个数据表存储的是一篇篇的文章,文章中的常见词、语气词等等,出现的肯定比较多,搜索这些词语就没什么意义了,需要搜索的是那些文章中有特殊意义的词,这样才能把文章区分开。
//使用方式
select * from test where match(content) against('aaaa');
select *, MATCH ( content) AGAINST ('aaaa') as score from test where MATCH ( content) AGAINST ('aaaa' IN NATURAL LANGUAGE MODE)
布尔全文索引
在布尔搜索中,我们可以在查询中自定义某个被搜索的词语的相关性,当编写一个布尔搜索查询时,可以通过一些前缀修饰符来定制搜索。
MySQL 内置的修饰符,上面查询最小搜索长度时,搜索结果 ft_boolean_syntax 变量的值就是内置的修饰符,下面简单解释几个,更多修饰符的作用可以查手册
- IN BOOLEAN MODE的特色:
- 不剔除50%以上符合的row。
- 不自动以相关性反向排序。
- 可以对没有FULLTEXT index的字段进行搜寻,但会非常慢。
- 限制最长与最短的字符串。
- 套用Stopwords。
- 搜索语法规则:
- + 一定要有(不含有该关键词的数据条均被忽略)。
- - 不可以有(排除指定关键词,含有该关键词的均被忽略)。
- > 提高该条匹配数据的权重值。
- < 降低该条匹配数据的权重值。
- ~ 将其相关性由正转负,表示拥有该字会降低相关性(但不像-将之排除),只是排在较后面权重值降低。
- * 万用字,不像其他语法放在前面,这个要接在字符串后面。
- " " 用双引号将一段句子包起来表示要完全相符,不可拆字。
//使用方式
select * test where match(content) against('a*' in boolean mode);
底层原理
全文索引的底层一般是采用倒层索引实现的
倒层索引
什么是倒层索引?倒排索引跟B+树一样,也是一种数据结构。
我们知道,正常情况下,我们去一个文件里面查找一串字符串,那么会从头开始扫描这个字符串,但是当需要扫描的文件多了起来,这种方式,就会十分消耗资源和时间。
倒排索引就是对于一个文件或者字段内容,将其拆分成一个个的单词(词语),拆分的大小根据上面的ngram配置,然后这样的一个个词映射了它存在于哪个文件,出现了多少次,所处文件的位置等等。
最后形成的一张表(或者其他的结构)就会保存这样的映射关系,这样下次我们就可以通过搜素关键字,来直接搜索这个映射表,来快速找到我们所查找的字符串所存在的文件
在information_schema可以查看fulltext索引的相关表
SET GLOBAL innodb_ft_aux_table = 'test/test';
INNODB_FT_INDEX_TABLE或者INNODB_FT_INDEX_CACHE就是对应的映射表
两种映射表存储方式
- full inverted index,这种方式会占用更多的空间,因为它不仅会存储单词和单词所在文档的ID,还会存储单词所在文档的ID中具体的位置
- inverted file index,只存储单词及对应的单词所在文档。这种节省空间,但是查找时,只能根据关键字得到相应文档,再进行查找
分词
通过上面的讲解,我们知道了,innodb会把单词拆分进行存储,查找时,根据单词匹配(默认是英文符号),但是有一些词,我们可能是不能索引查询的,比如’to’,这称之为stopword;
-- 默认停止词
SELECT * FROM information_schema.INNODB_FT_DEFAULT_STOPWORD;
或者word的字符长度不在innodb_ft_min_token_size到innodb_ft_max_token_size。默认是3-84个字符区间
当然,也可以定制stopword,可以参考mysql stopwords
相关性
如果一个查询,匹配到多条记录,是怎么返回呢?
-- 查询相关性
SELECT title, MATCH(title) AGAINST('like') AS relevance
FROM test
- word(查询关键字)是否在文档中出现 (出现了相关性肯定高)
- word在文档中出现的次数 (次数越多,相关性越高)
- word在索引列中的数量 (出现越多,该词的相关性分数越低,如“我们”二字,在文档中很容易出现)
- 多少个文档包含该word(同第三点)
参考链接
MyISAM 存储引擎支持全文索引(fulltext),用于查找文本中的关键词,而不是直接比较是否相等。
查找条件使用 MATCH AGAINST,而不是普通的 WHERE。
全文索引使用倒排索引实现,它记录着关键词到其所在文档的映射。
InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。
空间数据索引
参考链接
什么是空间数据索引
简单来说,我们有时候会需要对二维、三维等数据进行存储(如地图经纬度),空间数据索引就是为这种情况而设计的,用于简化大量地图数据的查询。
空间数据索引和普通查询方式有何区别
假设,我们有这样的一个需求,获取当前位置的附近5km的商家,并推荐给用户。那么我们肯定是获取到当前用户的经纬度,并去数据库查询附近5km的商家。
不使用索引
-
暴力方法:直接计算所有商家和现在位置的距离,两点间距离公式(这里采用最简单的,但其实地球是个不规整的球,距离公式还要复杂一点)
d = ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 d=\sqrt{(x1-x2)^2+(y1-y2)^2} d=(x1−x2)2+(y1−y2)2
那么该查询复杂度 数据总数次*复杂距离公式 -
矩形过滤方法:先圈出目前位置5km的矩形(正方形),然后我们要找的商家就是这个矩形的内切圆,判断是否在矩形中非常简单,只需要(假设目前位置精度为a,纬度为b)
{ a − 5 < x < a + 5 b − 5 < y < b + 5 \begin{cases} a-5<x<a+5\\ b-5<y<b+5\end{cases} {a−5<x<a+5b−5<y<b+5
然后对筛选出来的点进行距离公式,保留小于5km的点(假设筛选后还剩n个)那么该查询复查度 数据总数次*矩形筛选 + n*复杂距离公式
此方法节约了算法成本,但由于没有使用索引,遍历了全表
使用B+Tree索引
- 我们对纬度设置索引,虽然无法直接通过纬度,确定距离,但是我们可以简单将经纬度看成矩形过滤方法中的矩形(大不了我们选大一点),那么我们可以通过过滤函数筛选出符合条件的纬度(假设筛选后还有m条数据)
- 然后在对这m条数据,进行同样的经度筛选(假设筛选后还有n条数据)(这两步其实和矩形过滤方法是一样的,只是采用了索引,要更快)
- dui这n条数据再进行距离公式的筛选
- 最终的复杂度为: Log(数据总数次)*过滤函数+m*过滤函数+n*复杂距离公式;
这样就不用遍历全表,甚至如果我们同时对经度和纬度设置联合索引,查询还可以优化
但是这样也存在一些问题:
- 采用一维索引无法很好的展示经纬度的位置关系(只能左右或者上下,无法同时)
- 但数据是三维或更高时,才用联合索引,优先级不好确认(经纬度同样重要)
- 当空间数据不是点,而是线(道路、地铁、河流等),面(行政区边界、建筑物等),无法索引
空间数据索引
空间数据索引则根据空间位置进行存储,很快就能查找到附近的数据
支持的版本和引擎
- MySQL 5.7.4以前的版本,只有 MyISAM 存储引擎支持空间数据索引;
- MySQL5.7.4及以后的版本,MyISAM 和 InnoDB 存储引擎均支持空间数据索引;
使用方式
创建一个表和索引
CREATE TABLE `gim` (
`path` varchar(512) NOT NULL,
`box` geometry NOT NULL,
PRIMARY KEY (`path`),
SPATIAL KEY `box` (`box`)
) ;
插入数据,数据的插入和普通的数据插入一样,只是geometry
数据需要使用st_geomfromtext
等函数来构造,相关的文档参考在这里gis-data-formats还有这个populating-spatial-columns。
这里只展示一个简单数据插入,这里我使用的是单多边形,只有四个点(逆时针顺序),使用WKT描述几何数据。
insert into gim (path,box) values('%s',ST_GeomFromText(
'Polygon((116.18866 39.791107, 116.124115 39.791107, 116.18866 39.833679, 116.124115 39.833679, 116.18866 39.791107))'));
查询这里和普通的查询也一样,只是where
字句后面使用空间过滤相关选项就是。
使用空间索引进行查询的相关文档在这里using-spatial-indexes
一个简单的查询示例:
select * from gim where MBRContains(st_geomfromtext('polygon((116.438599 39.832306, 116.374054 39.832306, 116.438599 39.876251, 116.374054 39.876251, 116.438599 39.832306))'),box);
底层原理
传统索引使用哈希和树这两类最基本的数据结构。空间索引虽然更为复杂,但仍然发展于这两种数据结构。因此可以将空间索引划分为两大类:1)基于哈希思想,如网格索引等;2)基于树思想,有四叉树、R树等。
网格索引
对地理空间进行网格划分,划分成大小相同的网格,每个网格对应着一块存储空间,索引项登记上落入该网格的空间对象。
举个例子,我们将地理空间进行网格划分,并进行编号。该空间范围内有三个空间对象,分别是id=5的街道,23的河流和11的商圈。这时候我们可以按照哈希的数据结构存储,每个网格对应着一个存储桶,而桶里放着空间对象,比如对2号网格,里面存储着id=5的空间对象,对35号网格,桶里放着id=5和id=23的空间对象。那么可以看到街道途经2、34、35、67、68四个格子,河流途经5、37、36、35、67、99、98、97八个格子,商圈包含68、69、100、101四个格子。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6PYYuaTw-1618299272564)(https://note.youdao.com/yws/api/personal/file/49F9D6DA541D4B168E398A2EF2FA7D6B?method=download&shareKey=3dbe869c5f4f95db6374c5a41e2844bd)]
假如我们要查询某一空间范围内有哪些空间对象,比如下面的红框就表示空间范围,我们可以很快根据红框的空间范围算出它与35号和36号网格相交,然后分别到35号和36号网格中查找空间对象,最终找出id=5和id=23的空间对象。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TJQLQvnJ-1618299272567)(https://note.youdao.com/yws/api/personal/file/92017EBB2AFF451E9866979B5C47723D?method=download&shareKey=70f19d3582a03b8eeafa60f1fa6aacf0)]
所以总结如下:
- 首先将地图分为大大小小的格子,然后对每个格子进行hash运算,对应索引项
- 存储的数据,根据他所占据的格子,算出对应的索引项,并存储到相应的桶里
- 查询时,只需要查询对应的格子的桶里有哪些数据就可以了,比如用户在红圈的中间,那么方圆5公里可能就只需要查找35附近的几个格子就可以了
网格索引的缺点:
- 索引数据冗余,网格与对象之间多对多关系在空间对象数量多、大小不均时造成索引数据冗余。比如11号商圈这个空间对象在68,69,100,101这4个网格都有存储,浪费了大量空间。
- 网格的大小难以确定。网格划分得越密,需要的存储空间越多,网格划分的越粗,查找效率可能会降低。
- 很多网格没有数据空间数据具有明显的聚集性,比如商家可能只在几个热点商贸区聚集,在郊区等地方很稀疏,这将导致很多网格内没有任何空间数据。
四叉树
四元树又称四叉树是一种树状数据结构,在每一个节点上会有四个子区块。四元树常应用于二维空间数据的分析与分类。它将数据区分成为四个象限。(如果三维则可以衍生至八叉树)
四叉树可以认为是二叉查找树的高维变体,它适合对有二维属性的数据进行存储和查询,当然四叉树存储的也不一定是二维数据,而是有着二维属性的数据,如有着 x,y 信息的点,用它还可以用来存储线和面数据。它有四个节点,在数据插入时,我们通过其二维属性(一般是 x,y)选择四个叉之一继续向下,直至叶子结点,同样使用“四分法”来迅速查找数据。
四叉树是二叉树的扩展,那么对应B+Tree树,同样容易实现类似的四叉树
四叉树如下:字母代表区域,数字代表数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B2T8w3Yw-1618299272569)(https://note.youdao.com/yws/api/personal/file/79D5E32087DD452DA5849E351350705D?method=download&shareKey=0600741ed92f4720ca34c34b3adba888)]
总结如下:
- 四叉树也是首先将地图分成大小相同的格子,但是不同的是,他可以实现如果格子里没有数据,则不需要开辟空间来存储这一个格子(因为他是先生成满四叉树,然后释放没有数据的节点)
- 数据存储在能够完全包裹它的最小节点下,如2区域存储在b节点下
- 个人感觉,如果需要限制树的高度为3-7层之类,可以在将每个节点存放多颗数据(类似B+Tree),然后根据空间位置进行排序(先左右后上下)
四叉树的缺点:
- 数据量大了,树的层级会非常深
- 如果采用数据存储在能够完全包裹它的最小节点下,则无法精确定位节点位于这个最小节点的哪些子节点内
- 对于筛选出具体距离范围的,实现比较麻烦(如之前的5km,在得知用户的具体位置后,只能根据根节点一步步查找到和它同一个区域的数据,附近区域的数据则又需要从新查询整棵树)
R树
R树把B树的思想很好的扩展到了多维空间,采用了B树分割空间的思想,并在添加、删除操作时采用合并、分解结点的方法,保证树的平衡性。因此,R树就是一棵用来存储高维数据的平衡树。
R树是B树在高维空间的扩展,是一棵平衡树。每个R树的叶子结点包含了多个指向不同数据的指针,这些数据可以是存放在硬盘中的,也可以是存在内存中。根据R树的这种数据结构,当我们需要进行一个高维空间查询时,我们只需要遍历少数几个叶子结点所包含的指针,查看这些指针指向的数据是否满足要求即可。这种方式使我们不必遍历所有数据即可获得答案,效率显著提高。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EdtLx8lQ-1618299272572)(https://note.youdao.com/yws/api/personal/file/A3ACE7BDE2664B3B96C9FFB91D7576BF?method=download&shareKey=6818eb4dc6a2c87a933aaaea5a53fa54)]
详细解释一下这张图。先来看图(b)吧。首先我们假设所有数据都是二维空间下的点,图中仅仅标志了R8区域中的数据,也就是那个shape of data object。别把那一块不规则图形看成一个数据,我们把它看作是多个数据围成的一个区域。为了实现R树结构,我们用一个最小边界矩形恰好框住这个不规则区域,这样,我们就构造出了一个区域:R8。R8的特点很明显,就是正正好好框住所有在此区域中的数据。其他实线包围住的区域,如R9,R10,R12等都是同样的道理。这样一来,我们一共得到了12个最最基本的最小矩形。这些矩形都将被存储在子结点中。下一步操作就是进行高一层次的处理。我们发现R8,R9,R10三个矩形距离最为靠近,因此就可以用一个更大的矩形R3恰好框住这3个矩形。同样道理,R15,R16被R6恰好框住,R11,R12被R4恰好框住,等等。所有最基本的最小边界矩形被框入更大的矩形中之后,再次迭代,用更大的框去框住这些矩形。我想大家都应该理解这个数据结构的特征了。用地图的例子来解释,就是所有的数据都是餐厅所对应的地点,先把相邻的餐厅划分到同一块区域,划分好所有餐厅之后,再把邻近的区域划分到更大的区域,划分完毕后再次进行更高层次的划分,直到划分到只剩下两个最大的区域为止。要查找的时候就方便了吧。
下面就可以把这些大大小小的矩形存入我们的R树中去了。根结点存放的是两个最大的矩形(R1、R2),这两个最大的矩形框住了所有的剩余的矩形,当然也就框住了所有的数据。下一层的结点存放了次大的矩形,这些矩形缩小了范围。每个叶子结点都是存放的最小的矩形,这些矩形中可能包含有n个数据。
总结:
- R树是B树在高维空间的扩展,是一棵平衡树
- R树的实现方式和之前说的矩形过滤方法本质上是一样的
- 对于存储而言,每一条数据都是叶子节点,然后R树,会将相近的叶子节点合并成一个大矩形,形成它的父节点,然后将这些大矩形又形成更大的矩形,最终形成根节点,以满足树的深度在3-7之间。
- 对于查询而言,先找到包含用户位置的最小矩形,然后对该矩形的数据进行筛选,以满足附近5km的需求
- 那么很多时候,我们会直接将地图作为一张表,存储划分到一个个区域的数据(矩形),商家再作为一张表,存储其属于哪一个区域(这样就可以实现快速查找)
一棵R树满足如下的性质:
- 除根结点之外,所有叶子结点包含有m至M个记录索引(条目)。作为根结点的叶子结点所具有的记录个数可以少于m。通常,m=M/2。
- 对于所有在叶子中存储的记录(条目),I是最小的可以在空间中完全覆盖这些记录所代表的点的矩形(注意:此处所说的“矩形”是可以扩展到高维空间的)。
- 每一个非叶子结点拥有m至M个孩子结点,除非它是根结点。
- 对于在非叶子结点上的每一个条目,i是最小的可以在空间上完全覆盖这些条目所代表的店的矩形(同性质2)。
- 所有叶子结点都位于同一层,因此R树为平衡树。
自适应哈希索引
参考链接
底层原理
哈希(hash)是一种非常快的查找方法,在一般情况下这种查找的时间复杂度为O(1),即一般仅需要一次查找就能定位数据。而B+树的查找次数,取决于B+树的高度,在生产环境中,B+树的高度一般为34层,故需要34次的查询。
InnoDB存储引擎会监控对表上各索引页的查询。如果观察到建立哈希索引可以带来速度提升,则建立哈希索引,称之为自适应哈希索引(Adaptive Hash Index,AHI) AHI是通过缓冲池的B+树页构造而来,因此建立的速度很快,而且不需要对整张表构建哈希索引。 InnoDB存储引擎会自动根据访问的频率和模式来自动地为某些热点页建立哈希索引。
AHI有一个要求,即对这个页的连续访问模式必须是一样的。例如对于(a,b)这样的联合索引页,其访问模式可以是以下情况:
- WHERE a=xxx
- WHERE a= xxx and b=xxx
访问模式一样指的是査询的条件一样,若交替进行上述两种查询,那么 InnoDB存储引擎不会对该页构造AH此外AH还有如下的要求:
- 以该模式访问了100次
- 通过该模式访问了N次,其中N=页中记录/16
根据 InnoDB存储引擎官方的文档显示,启用AHI后,读取和写入速度可以提高2倍,辅助索引的连接操作性能可以提高5倍。毫无疑问,AHI是非常好的优化模式,其设计思想是数据库自优化的(self-tuning),即无需DBA对数据库进行人为调整。
值得注意的是,哈希索引只能用来搜索等值的查询,如 SELECT * FROM table WHERE index_col=‘xxx’。而对于其他查找类型,如范围查找,是不能使用哈希索引的,因此这里出现了non-hash searches/s的情况。通过 hash searches: non-hash searches可以大概了解使用哈希索引后的效率。
由于AHI是由 InnoDB存储引擎控制的,因此这里的信息只供用户参考。不过用户可以通过观察 SHOW ENGINE INNODB STATUS的结果及参数 innodb_adaptive_hash_index来考虑是禁用或启动此特性,默认AHI为开启状态。