繁体   English   中英

为什么 InnoDB 在创建表时需要聚集索引?

[英]Why does InnoDB require clustered index upon creating a table?

即使我没有主键或唯一键,InnoDB 仍然会在合成列上创建集群索引,如下所述。

https://dev.mysql.com/doc/refman/5.5/en/innodb-index-types.html

那么,为什么 InnoDB 必须需要聚集索引? 这里必须存在聚集索引是否有明确的原因?

在 Oracle 数据库或 MSSQL 中,我认为他们不需要这个。 另外,我认为集群索引与普通表相比也没有那么大的优势。

确实,使用集群键查找数据不需要额外的磁盘读取,并且比没有集群索引但没有集群索引时更快,二级索引可以通过使用物理 rowID 更快地查找。 因此,我看不出有任何理由坚持使用它。

其他供应商有一个“ROWNUM”或类似的东西。 InnoDB 要简单得多。 而不是拥有那种动物,它只是需要一些你通常想要的东西。 在这两种情况下,它都是唯一标识行的值。 这是事务的核心所必需的——知道要锁定哪一行,等等,以提供事务完整性。 (我不会在这里讨论基本原理。)

在要求(或提供)PK 以及进行某些其他简化时,InnoDB 牺牲了几个很少使用(或易于解决)的功能:多个 pk、多个聚集索引、无 pk 等。

由于“合成列”需要 6 个字节,因此即使您不使用它,简单地提供id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY几乎总是更好。 但是,如果您不使用它,但确实有一个非 NULL UNIQUE键,那么您不妨将其设为 PK。 (正如 MySQL 默认所做的那样。)

通过辅助键的查找首先从辅助键的 BTree 中获取 PK 值。 然后向下钻取主 BTree(具有按 PK 排序的数据)以查找行。 因此,辅助密钥可能比使用 PK 更慢。 (通常这还不够慢。)因此,这指出了一个需要PK 的设计决策。)(其他供应商使用 ROWNUM 或其他东西来定位记录,而不是 PK。)

回到“为什么?”。 在 MySQL 中有很多决定,其中设计者说“对于这个免费产品来说,简单更好,让我们不要费心构建一些复杂但很少使用的功能。起初没有子查询(临时表是一种解决方法)。没有视图(他们只是语法糖。没有物化视图(好吧,这可能是一个失败;但它们可以被模拟)。没有位图或哈希或 isam(等)索引(BTree 非常适合“全方位”使用) .

此外,通过始终将 PK 与数据“聚类”,通过 PK 进行的查找本质上比竞争对手更快(无需通过 ROWNUM)。 (辅助键查找可能不会更快。)

另一个区别——MySQL 在实现“索引合并”方面很晚,它使用两个索引,然后对结果进行 AND 或 OR 运算。 这对于 ROWNUM 可能是有效的,但对于集群 PK 则无效。

(我不是 MySQL/MariaDB/Percona 开发人员,但我从 1999 年开始使用它们,并且几乎参加了所有主要的 MySQL 会议,其中经常泄露内部信息。所以,我想我对他们的想法有足够的了解提出这个答案。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM