mysql 或 mariadb 是否有 SQL Server 索引的“包含列”的概念?

Joe*_*ips 2 mysql mariadb index

在 SQL Server 中,您可以创建一个索引并在该索引中包含其他列,这有助于在某些情况下提高性能。mysql 或 mariadb 是否可以以不同的名称使用相同的功能?我无法使用术语“包含的列”找到任何内容。

Han*_*non 5

查看 MySQL 文档,词汇表指出了有关Covering Indexes 的这一点:

包含查询检索到的所有列的索引。查询不使用索引值作为查找完整表行的指针,而是从索引结构返回值,从而节省磁盘 I/O。InnoDB 可以将这种优化技术应用于比 MyISAM 更多的索引,因为 InnoDB 二级索引还包括主键列。InnoDB 不能将此技术应用于针对事务修改的表的查询,直到该事务结束。

给定正确的查询,任何列索引或复合索引都可以充当覆盖索引。设计您的索引和查询以尽可能利用这种优化技术。

这里的含义是INCLUDE在 MySQL 中没有直接等价的语句,但是如果索引提供了索引中涉及的列的覆盖,很明显,它仍然可以被认为是覆盖的,就像包含列的索引一样在 SQL Server 中。

MariaDB 在其涵盖索引的文档中包含以下内容:

“覆盖”索引是包含 SELECT 中所有列的索引。特殊之处在于仅查看 INDEX BTree 即可完成 SELECT。(由于 InnoDB 的 PRIMARY KEY 与数据聚集在一起,因此在 PRIMARY KEY 上考虑时“覆盖”没有任何好处。)

迷你食谱:

  1. 根据上面的“算法”收集列列表。
  2. 以任何顺序将 SELECT 中看到的其余列添加到列表的末尾。

例子:

SELECT x FROM t WHERE y = 5; ? INDEX(y,x) -- The algorithm said just INDEX(y)  
SELECT x,z FROM t WHERE y = 5 AND q = 7; ? INDEX(y,q,x,z) -- y and q in either order (Algorithm), then x and z in either order (covering).  
SELECT x FROM t WHERE y > 5 AND q > 7; ? INDEX(y,q,x) -- y or q first (that's as far as the Algorithm goes), then the other two fields afterwards.   
Run Code Online (Sandbox Code Playgroud)

您获得的加速可能很小,也可能很惊人;很难预测。

但...

  • 构建包含大量列的索引是不明智的。让我们在 5 点(经验法则)切断它。
  • 前缀索引不能“覆盖”,所以不要在“覆盖”索引的任何地方使用它们。
  • 索引的“宽度”有限制(3KB?),因此“覆盖”可能是不可能的。

  • INCLUDE 功能通常与唯一索引一起使用,这样即使包含的列不是唯一约束的一部分,您仍然可以获得“覆盖索引”。 (2认同)