InnoDB二级索引包含值而不是指向PK的指针,这足够了吗?

时间:2019-06-15 09:41:58

标签: mysql indexing innodb myisam

我正在阅读Effective Mysql - Optimizing Mysql Statements,在chapter 3中有这样的解释:

  

InnoDB中的二级索引使用B树数据结构;但是,它们不同于MyISAM的实现。 在InnoDB中,辅助索引存储主键的物理值。在MyISAM中,辅助索引存储指向包含主键值的数据的指针。

     

这很重要,原因有两个。首先,当定义了较大的主键时,例如,当您在InnoDB中的主键长度为40个字节时,InnoDB中的二级索引的大小可能会更大。随着二级索引数量的增加,索引的比较大小可能变得很重要。第二个区别是辅助索引现在包含主键值,并且 不需要作为索引的一部分。 这可以通过表连接和覆盖显着提高性能索引。

我想到了很多问题,主要是由于对作者试图传达的内容缺乏了解。

  1. 目前尚不清楚作者在 第二段。不再需要什么 作为索引的一部分

  2. InnoDB二级索引B树仅存储PK值还是PK值 和指针吗?还是PK值和指向数据行的指针?

  3. 由于存储方法(第二个问题的答案)会带来什么样的性能提升?

This问题包含一个示例以及一个答案。他解释了它如何包含PK值,但是我仍然不了解的是,

要完成连接,如果指针不在二级索引中,而只有该值,MySQL不会使用二级索引中的值对主键索引进行全索引扫描吗?这比拥有指针还有效吗?

2 个答案:

答案 0 :(得分:2)

基础。

MyISAM的主键和辅助键的工作方式相同。 -两者都是.MYI文件中的BTree,叶节点中的“指针”指向.MYD文件。

“指针”可以是.MYD文件的字节偏移量,也可以是记录编号(对于FIXED)。两者都会导致对.MYD文件的“搜索”。

InnoDB的数据(包括PRIMARY KEY的列)存储在PK排序的一个BTree中。

这使PK查找略快一些。两者都钻取了一个BTree,但是MyISAM需要额外的搜索。

每个InnoDB次要密钥存储在单独的BTree中。但是在这种情况下,叶节点包含PK的任何其他列。因此,辅助键查找首先根据辅助键深入该BTree。在那里将找到辅助键和主键的所有列。 如果这些都是您需要的所有列,则这是查询的“覆盖索引”,无需进一步操作。 (比MyISAM快。)

但是通常您需要一些其他列,因此PK的列用于向下钻取数据/ PK BTree来查找行中的其余列。 (比MyISAM慢。)

因此,在某些情况下,MyISAM的工作量较少。在某些情况下,InnoDB的工作量较少。还有很多其他事情正在发生。 InnoDB在MyISAM上赢得了许多比较基准。

正在缓存...

MyISAM控制key_buffer中1KB索引块的缓存。数据块由操作系统缓存。

InnoDB在buffer_pool中同时缓存数据索引块和辅助索引块(两种情况下均为16KB)。

“缓存”是指根据需要用大致“最近最少使用”的算法来交换块。

没有BTree加载到RAM中。没有BTree被明确地保存在RAM中。每个块都根据需要进行请求,并且希望将该块缓存在RAM中。对于小于关联缓冲区(key_buffer / buffer_pool)的数据和/或索引,BTree 可能会发生停留在RAM中直到关机。

真相源在磁盘上。 (好的,在将块刷新到磁盘之前发生崩溃时,InnoDB会使用复杂的技巧来避免日志数据丢失。当崩溃后重新启动时,清理会自动发生。)

拔插头。

MyISAM:
混乱#1:索引将处于不干净的状态。需要CHECK TABLEREPAIR TABLE
混乱#2:如果您在一个语句中位于UPDATEing的一千行中间,则某些将被更新,而某些则不会。

InnoDB:
如上所述,InnoDB即使在拔插头的情况下,也会执行原子的功能。没有索引被遗忘。 UPDATE的所有内容都未完成。将会是ROLLBACKed

示例。

给予

columns a,b,c,d,e,f,g
PRIMARY KEY(a,b,c)
INDEX(c,d)

BTree叶子节点将包含:

MyISAM:
PK:a,b,c,pointer
中学:c,d,pointer

InnoDB:
PK:a,b,c,d,e,f,g(整行与PK一起存储)
中学:c,d,a,b

答案 1 :(得分:1)

二级索引是访问数据的间接方式。与主(聚集)索引不同,在InnoDB中遍历辅助索引并到达叶节点时,您会找到查询要查找的对应行的主键 value 。使用此值可以遍历主索引以获取行。这意味着在InnoDB中 2个索引查找
对于MyISAM,因为辅助节点的叶子是指向实际行的指针,所以只需要1次索引查找。

二级索引是基于表的某些非PK属性形成的。因此,根据定义,PK不必成为索引的一部分。无论是(InnoDB)还是(MyISAM)都是具有相应性能影响的实现细节。
现在,与MyISAM(2次查询vs 1次查询)相比,InnoDB最初采用的方法似乎效率低下,但这不是因为主索引保留在内存中所以代价很低。
但是优点是InnoDB可以拆分和移动行以优化行的插入/更新/删除中的表布局,而无需在二级索引上进行任何更新,因为它不会直接引用受影响的行