MyISAM与InnoDB索引实现对比详解

MyISAM索引实现

MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。如图:

这里设表一共有三列,假设我们以Col1为主键,则上图是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示:

同样也是一颗B+Tree,data域保存数据记录的地址。因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。
MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分。

InnoDB索引实现

虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。

第一个重大区别是InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。

上图是InnoDB主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。例如,下图为定义在Col3上的一个辅助索引:

这里以英文字符的ASCII码作为比较准则。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。

总结

在数据库开发中,了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助。例如,知道了InnoDB的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。再例如,用非单调的字段作为主键在InnoDB中不是个好做法,因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。

到此这篇关于MyISAM与InnoDB索引实现对比的文章就介绍到这了,更多相关MyISAM与InnoDB索引对比内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL数据库修复方法(MyISAM/InnoDB)

    在网上找了篇MySQL的技术文章,感觉不错,把它翻译过来共享下.   原文作者:Mike Peters   我整理了7条修复MySQL数据库的方法,当简单的重启对数据库不起作用,或者有表崩溃时.   简单的MySQL重启:   /usr/local/mysql/bin/mysqladmin -uUSERNAME -pPASSWORD shutdown /usr/local/mysql/bin/mysqld_safe &    1.MyISAM表崩溃    MySQL数据库允许不同的表使用不同的存

  • MySQL从MyISAM转换成InnoDB错误与常用解决办法

    原来自己用的是为了装的, 所以在设置database usage(如下图1)的时候按照discuz官方的建议,选的都是Non-Transactional Database Only(只支持MyISAM数据引擎的非事务数据库),用MyISAM数据库,还没涉及到需要InnoDB,因此打算直接不加载INNODB引擎.后来在做WordPress,一开始还不知道原来WordPress用的是InnoDB数据引擎,于是在原来的数据库里面就建了一个数据库,一开始也没发觉问题,安装,导入sql,都没问题,当时也没

  • 浅谈MySQL存储引擎选择 InnoDB与MyISAM的优缺点分析

    下面先让我们回答一些问题: ◆你的数据库有外键吗? ◆你需要事务支持吗? ◆你需要全文索引吗? ◆你经常使用什么样的查询模式? ◆你的数据有多大? 思考上面这些问题可以让你找到合适的方向,但那并不是绝对的.如果你需要事务处理或是外键,那么InnoDB 可能是比较好的方式.如果你需要全文索引,那么通常来说 MyISAM是好的选择,因为这是系统内建的,然而,我们其实并不会经常地去测试两百万行记录.所以,就算是慢一点,我们可以通过使用Sphinx从InnoDB中获得全文索引. 数据的大小,是一个影响你

  • mysql更改引擎(InnoDB,MyISAM)的方法

    本文实例讲述了mysql更改引擎(InnoDB,MyISAM)的方法,分享给大家供大家参考.具体实现方法如下: mysql默认的数据库引擎是MyISAM,不支持事务和外键,也可使用支持事务和外键的InnoDB. 查看当前数据库的所支持的数据库引擎以及默认数据库引擎 数据库支持的引擎和默认数据库引擎代码: 复制代码 代码如下: show engines; 更改方式1:修改配置文件my.ini 我将my-small.ini另存为my.ini,在[mysqld]最后添加为上default-storag

  • MySQL存储引擎MyISAM与InnoDB区别总结整理

    1.MySQL默认存储引擎的变迁 在MySQL 5.1之前的版本中,默认的搜索引擎是MyISAM,从MySQL 5.5之后的版本中,默认的搜索引擎变更为InnoDB. 2.MyISAM与InnoDB存储引擎的主要特点 MyISAM存储引擎的特点是:表级锁.不支持事务和全文索引,适合一些CMS内容管理系统作为后台数据库使用,但是使用大并发.重负荷生产系统上,表锁结构的特性就显得力不从心: 以下是MySQL 5.7 MyISAM存储引擎的版本特性: InnoDB存储引擎的特点是:行级锁.事务安全(A

  • 将MySQL从MyISAM转换成InnoDB错误和解决办法

    后来在做WordPress,一开始还不知道原来WordPress用的是InnoDB数据引擎,于是在原来的数据库里面就建了一个数据库,一开始也没发觉问题,安装,导入sql,都没问题,当时也没多想.直到这几天因为又要装多一个WordPress,用phpmyadmin访问数据库多一点,问题来了.老是一访问WordPress的数据库,就弹出错误提示"Mysqld-nt.exe应用程序错误:"0x005346c4"指令引用的"0x00786000"内存,该内存不能为

  • mysql中engine=innodb和engine=myisam的区别介绍

    最开始用MySQL Administrator建数据库的时候,表缺省是InnoDB类型,也就没有在意.后来用Access2MySQL导数据的时候发现只能导成 MyISAM类型的表,不知道这两种类型有什么区别,就去查了查.原来是MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持. MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持已经外部键等高级数据库功能.这 样就可以根据数据表不同的用处是用不同的存储类型. 另外,My

  • MySQL存储引擎 InnoDB与MyISAM的区别

    基本的差别:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持以及外部键等高级数据库功能.以下是一些细节和具体实现的差别:1.InnoDB不支持FULLTEXT类型的索引.2.InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即

  • MySQL存储引擎中的MyISAM和InnoDB区别详解

    在使用MySQL的过程中对MyISAM和InnoDB这两个概念存在了些疑问,到底两者引擎有何分别一直是存在我心中的疑问.为了解开这个谜题,搜寻了网络,找到了如下信息: MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然性能极佳,但却有一个缺点:不支持事务处理(transaction).不过,在这几年的发展下,MySQL也导入了InnoDB(另一种数据库引擎),以强化参考完

  • MySQL两种表存储结构MyISAM和InnoDB的性能比较测试

    MySQL支持的两种主要表存储格式MyISAM,InnoDB,上个月做个项目时,先使用了InnoDB,结果速度特别慢,1秒钟只能插入10几条.后来换成MyISAM格式,一秒钟插入上万条.当时决定这两个表的性能也差别太大了吧.后来自己推测,不应该差别这么慢,估计是写的插入语句有问题,决定做个测试:测试环境:Redhat Linux9,4CPU,内存2G,MySQL版本为4.1.6-gamma-standard测试程序:Python+Python-MySQL模块.测试方案:1.MyISAM格式分别测

随机推荐