innodb(pk,col1,col2,col3)形式的覆盖索引是否冗余?

qzlgjiam  于 2021-06-25  发布在  Mysql
关注(0)|答案(1)|浏览(402)

表的表结构 config :
属性(主键)
价值
描述
查询:

SELECT property, value FROM config

如果我把覆盖索引放在 (property, value) 优化器仍然选择 PRIMARY 索引,但是 extraEXPLAINNULL . 如果我告诉优化器使用我的覆盖索引 extraEXPLAINUSING INDEX .
这里到底发生了什么?为什么优化器选择 PRIMARY 默认情况下,索引在我的覆盖索引之上?我是不是告诉优化器使用我的覆盖索引来避免磁盘io?

mccptt67

mccptt671#

innodb索引不会自动存储在缓冲池中。它们存储在磁盘上。索引页和数据页都存储在磁盘上。
索引页和数据页都可以复制到内存中的缓冲池中,这取决于以前的查询是否请求它们。但这并不能保证。
实际上,当我说“数据页”时,实际上是聚集索引,即主索引。innodb将所有内容存储为索引。对于主索引/聚集索引,每个条目都包括所有其他列。这有效地使主索引成为“数据页”。在某些数据库中,它们使用术语“索引组织表”
当优化器选择主索引时,不言而喻,主键读取将能够获得所有其他列,而无需进一步查找(除了扩展到额外页面的blob/text数据)。
explain报告中的“using index”注解仅在查询从索引中读取所需的所有列时出现,并且索引是辅助索引(不是主索引)。
“使用索引”与内存中的与从磁盘读取无关。当请求一个页时,如果它在缓冲池中,它将从内存中读取。如果它不在缓冲池中,它将从磁盘复制到缓冲池中,不管它是主索引还是次索引。
事实上,当优化器报告“using index”时,它不知道相应索引的所有、部分或没有页面在缓冲池中,还是尚未从磁盘加载。它只知道可以从一个二级索引中获得所需的所有列,而不必读取聚集索引。
请回复您的意见:
是的,整行都在内存中,而不仅仅是pk。
缓冲池包含页,与磁盘上的页完全相同。页面包含两行或多行数据,这意味着主键加上与该主键相关的列。当从磁盘读取页时,会在缓冲池中创建一个副本。它就这样,一个字节一个字节地复制磁盘上的内容。
查询只读取缓冲池中页中存储的行。如果请求的行还未在内存中,则保存该行的页将立即从磁盘读取到缓冲池中,然后查询继续从内存中读取该行。
如果您需要磁盘中的其他页,并且缓冲池已满,则可以从缓冲池中逐出页。因此,缓冲池可能比磁盘上的总数据库小得多。随着时间的推移,最常用的页面往往停留在缓冲池中。

相关问题