综合指数的开销

时间:2015-09-06 00:10:33

标签: mysql innodb composite-index

我有很多表,其中我有外键索引,以及包含这些外键的聚簇索引。例如,我有一个如下表:

TABLE: Item
------------------------
id       PRIMARY KEY
owner    FOREIGN KEY
status

... many more columns

MySQL为主键和外键生成索引,但有时,我想提高查询性能,因此我将创建聚簇索引或覆盖索引。这导致索引具有重叠列。

INDEXES ON: Item
------------------------
idx_owner (owner)
idx_owner_status (owner, status)

如果我删除了idx_owner,那么通常使用idx_owner的未来查询只会使用idx_owner_status,因为它有owner作为索引中的第一列。

是否值得保持idx_owner?使用idx_owner_status是否还有额外的I / O开销,即使MySQL只使用索引的一部分?

编辑:我真的只对 InnoDB 关于索引的行为感兴趣。

1 个答案:

答案 0 :(得分:6)

简答 删除较短的索引。

Long Anwser 需要考虑的事项:

放弃它:

  • 每个INDEX都是一个独立的BTree,驻留在磁盘上,因此占用空间。
  • INDEX新行或INSERT修改索引列时,每个UPDATE都会更新(迟早)。这需要一些CPU和I / O以及缓冲区空间用于“更改缓冲区”。
  • 较短索引的任何功能使用(与性能相对)可以由较长的索引执行。

不要放弃它:

  • 较长的索引比较短的索引更笨重。所以它的可缓存性较差。所以(在极端情况下)使用较大的一个代替较短的一个可以导致更多的I / O.一个加剧这种情况的案例:INDEX(int, varchar255)

最后一项真的会覆盖其他项目的情况非常罕见。

<强>加成

A&#34;覆盖&#34; index是包含 all SELECT中提到的列的索引。例如:

SELECT status FROM tbl WHERE owner = 123;

这将只触及 BT INDEX(owner, status),因此明显快于

SELECT status, foo FROM tbl WHERE owner = 123;

如果您确实需要更快的查询,请将{em>两个的索引替换为INDEX(owner, status, foo)

辅助密钥中的PK

再多一点......在InnoDB中,PRIMARY KEY的列被隐式附加到每个二级密钥。所以,这三个例子真的是

INDEX(owner, id)
INDEX(owner, status, id)
INDEX(owner, status, foo, id)
composite indexesindex cookbook的博客中

更多讨论