警惕 InnoDB 和 MyISAM 创建 Hash 索引陷阱
比方表 data_dict 的 DDL:
CREATE TABLE `data_dict` (
`data_type` varchar(32) NOT NULL COMMENT '数据字典类型',
`data_code` tinyint(4) NOT NULL COMMENT '数据字典代码',
`data_name` varchar(64) NOT NULL COMMENT '数据字典值',
PRIMARY KEY (`data_type`,`data_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='数据字典表';
我们为 data_name 字段建立 Hash 索引:
ALTER TABLE data_dict ADD INDEX data_dict_dn USING HASH (data_name);
打印结果:
受影响的行: 0
时间: 0.345s
然后查看建表 DDL:
SHOW CREATE TABLE data_dict;
打印结果:
CREATE TABLE `data_dict` (
`data_type` varchar(32) NOT NULL COMMENT '数据字典类型',
`data_code` tinyint(4) NOT NULL COMMENT '数据字典代码',
`data_name` varchar(64) NOT NULL COMMENT '数据字典值',
PRIMARY KEY (`data_type`,`data_code`),
KEY `data_dict_dn` (`data_name`) USING HASH
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='数据字典表'
是 Hash,所以我们以为创建 Hash 索引成功。
其实并不是如此,我们都被 MySql 给骗了,我们使用 SHOW INDEXES FROM 语句对该表索引进行检索:
SHOW INDEXES FROM data_dict;
打印结果:
打回原形了。只是也不要失望,尽管常见存储引擎并不支持 Hash 索引,但 InnoDB 有还有一种实现方法:自适应哈希索引。InnoDB 存储引擎会监控对表上索引的查找。假设观察到建立哈希索引能够带来速度的提升,则建立哈希索引。
我们能够通过 SHOW ENGINE INNODB STATUS 来查看当前自适应哈希索引的使用状况:
=====================================
2015-07-07 10:51:19 1d68 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 36 seconds
......
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 2633, seg size 2635, 0 merges
merged operations:
insert 0, delete mark 0, delete 0
discarded operations:
insert 0, delete mark 0, delete 0
Hash table size 348731, node heap has 2 buffer(s)
0.00 hash searches/s, 0.00 non-hash searches/s
......
从中我们能够看到自适应哈希索引的相关信息:有使用大小、使用情况、每秒使用自适应哈希索引搜索的情况等。
MySql 各种存储引擎的特性对照详单:
从中我们能够看出,
- InnoDB 支持事务。支持行级别锁定。支持 B-tree、Full-text 等索引。不支持 Hash 索引。
- MyISAM 不支持事务,支持表级别锁定,支持 B-tree、Full-text 等索引。不支持 Hash 索引;
- Memory 不支持事务,支持表级别锁定。支持 B-tree、Hash 等索引,不支持 Full-text 索引。
- NDB 支持事务,支持行级别锁定。支持 Hash 索引。不支持 B-tree、Full-text 等索引;
- Archive 不支持事务。支持表级别锁定,不支持 B-tree、Hash、Full-text 等索引。
能够使用 SHOW ENGINES 语句查看你的 MySql Server 所支持的存储引擎,比方笔者用于本机測试的 5.6.25-log Win 版的查看结果例如以下:
从中能够看出。InnoDB 是该版本号 MySql 的默认存储引擎。也仅仅有 InnoDB 能够支持事务、行级别锁定、外键。支持的 MEMORY 是基于哈希的,数据都存放于内存。适用于暂时表。没有看到既支持事务又支持哈希索引的 NDB 的身影。
为印证默认的存储引擎,我们创建一个測试表 data_dict_test。注意建表语句里未定义存储引擎:
CREATE TABLE `data_dict_test` (
`data_type` varchar(32) NOT NULL COMMENT '数据字典类型',
`data_code` tinyint(4) NOT NULL COMMENT '数据字典代码',
`data_name` varchar(64) NOT NULL COMMENT '数据字典值',
PRIMARY KEY (`data_type`,`data_code`)
) DEFAULT CHARSET=utf8 COMMENT='数据字典表';
打印结果:
[SQL] CREATE TABLE `data_dict_test` (
`data_type` varchar(32) NOT NULL COMMENT '数据字典类型',
`data_code` tinyint(4) NOT NULL COMMENT '数据字典代码',
`data_name` varchar(64) NOT NULL COMMENT '数据字典值',
PRIMARY KEY (`data_type`,`data_code`)
) DEFAULT CHARSET=utf8 COMMENT='数据字典表';
受影响的行: 0
时间: 0.262s
然后查看建表 DDL:
SHOW CREATE TABLE data_dict_test;
打印结果:
CREATE TABLE `data_dict_test` (
`data_type` varchar(32) NOT NULL COMMENT '数据字典类型',
`data_code` tinyint(4) NOT NULL COMMENT '数据字典代码',
`data_name` varchar(64) NOT NULL COMMENT '数据字典值',
PRIMARY KEY (`data_type`,`data_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='数据字典表'
这次 SHOW CREATE TABLE 没有欺骗我们,明白给出的就是 InnoDB,尽管我们建表时没有指定。
笔者建议使用 SHOW TABLE STATUS 语句来查看特定表的存储引擎:
SHOW TABLE STATUS WHERE NAME = 'data_dict_test';
打印结果:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="SHOW TABLE STATUS WHERE NAME = 'data_dict_test'" />
參考资料
警惕 InnoDB 和 MyISAM 创建 Hash 索引陷阱的更多相关文章
- 【Mysql】mysql使用触发器创建hash索引
概述 若设计的数据表中,包含较长的字段,比如URL(通常都会比较长),查询时需要根据该字段进行过滤: select * from table_xxx where url = 'xxxxxxx'; 为了 ...
- mysql InnoDB引擎是否支持hash索引
看一下mysql官方文档:https://dev.mysql.com/doc/refman/5.7/en/create-index.html , 从上面的图中可以得知,mysql 是支持hash索引的 ...
- innodb和myisam对比及索引原理区别
InnoDB和MyISAM是很多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,5.7之后就不一样了 1.事务和外键 InnoDB具有事务,支持4个事务隔离级别,回滚,崩溃修复能力和多版 ...
- MySQL的btree索引和hash索引的区别
Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-T ...
- MySQL两大存储引擎InnoDB与MyISAM
1.InnoDB存储引擎 MySQL5.5中InnoDB成为默认的存储引擎.InnoDB是事务型存储引擎,被设计用来处理大量的短期事务.它的性能和自动崩溃恢复特性,使得它在非事务场景中也很流行. 所以 ...
- B+索引、Hash索引、数据类型长度
1.为什么在数据库中要用B树索引而不是Hash索引? Mysql Hash索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这 ...
- Hash索引和BTree索引区别【转】
索引是帮助mysql获取数据的数据结构.最常见的索引是Btree索引和Hash索引. 不同的引擎对于索引有不同的支持:Innodb和MyISAM默认的索引是Btree索引:而Mermory默认的索引是 ...
- mysql索引hash索引和b-tree索引的区别
Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-T ...
- MySQL的btree索引和hash索引的区别 (转)
Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-T ...
随机推荐
- layui中选中select标签 隐藏div
在select标签中添加 lay-filter="cartype" <script type="text/javascript"> form.on( ...
- js&jQ判断checkbox表单是否被选中
js判断: if(document.getElementById("checkboxID").checked){ alert("checkbox is checked&q ...
- frameset宽屏居中写法
在写frameset的时候发现页面较小的时候不能在屏幕上居中,记录一下frameset页面居中的写法 <frameset cols="*,1280,*" frameborde ...
- 3ds Max灯光教程之卧室灯光布局实例
对于设计师来说要做好一张好的作品效果图包括很多比如:“造型.色彩搭配.灯光气氛.构图角度等等,上次给大家详细的分析了下产品渲染中摄像机的构图及原理.本期教程来跟大家讨论一下max场景灯光布局问题.以卧 ...
- 小程序使用wepy框架自定义loading组件
1:定义组 <template> <view class="app-loading-container" style="{{options.cssTex ...
- WebLogic 服务器配置
环境版本 Windows 8.1 WebLogic 10.3.0 JDK:1.6 WebLogic 创建域在Windows环境下有两种方式: 1.直接在开始菜单创建domai ...
- 【codeforces 496E】Distributing Parts
[题目链接]:http://codeforces.com/contest/496/problem/E [题意] 给你n个歌曲; 每个歌曲有一个需要声音的区间li,ri; 然后给你m个人; 每个人也有一 ...
- Gradle学习之自己定义属性
请通过下面方式下载本系列文章的Github演示样例代码: git clone https://github.com/davenkin/gradle-learning.git 在前面的文章中我们 ...
- ural 1989(树状数组+多项式hash)
题意:给出一个字符串.有两种操作,一个是p a b,问字符串从位置a到位置b的子串是否是一个回文子串.还有一个操作 c a b,把字符串位置a的字符替换为b. 题解:由于字符串长度为1e5且问的次数也 ...
- 漫谈linux之文件IO篇(SSD写性能和机械硬盘差不多,读是4到10倍)
前同事的文章,觉得写得很清晰,收藏了. http://blog.chinaunix.net/uid-27105712-id-3270102.html 在Linux 开发中,有几个关系到性能的东西,技术 ...