MySQL/MariaDB 中复合索引的大小是多少

问题描述

假设我有三列,A、B、C。它们分别具有 x、y 和 z 可能值 的范围。

所有三列上的索引的大小是否都与 x * y * z 成正比?

解决方法

没有。 INDEX 的大小是(大致)

  N * L + overhead

N = 整个表中的行数。
L = 索引所有列中值的长度(以字节为单位),加上 PRIMARY KEY 中的列。
开销 = 各种指针、长度、填充等

示例:CREATE TABLE ... id INT PRIMARY KEY,A INT,INDEX(A) ...

INT 是一个 4 字节的数据类型。它可以容纳超过 40 亿个不同的值。如果表中有 100 行,让我们看看持有辅助 INDEX(A) 的 BTree。

N = 100
L = 4 + 4  -- that bytes,not billions of bytes

N * L = 800,但是一旦增加了开销,并且使用了阻塞,就会占用 16KB。 (注意:InnoDB 以 16KB 的“块”分配数据和索引。)

现在添加到该表

city VARCHAR(100),-- average length 10 characters
INDEX(city,A)

N = 100  -- still assuming 100 rows
L = (2+10) + 4 + 4 = 16
total = again,only 1-2 blocks.

(2+10):2 为字符串的“长度”;实际字符串平均为 10。 (在某些情况下,“2”实际上是“1”,如果您使用的是 utf8,则每个 字符 可能是多个 字节。)

如果该表增长到 100 万行,索引可能需要 50MB,其中很多是不可避免的“开销”。

一个主要的例外:

对于 InnoDB,PRIMARY KEY 的大小几乎为零,因为它与数据“聚集”在一起。实际上,该 BTree 中的非叶节点还有大约 1% 的额外开销和一些“开销”。