我有很多表,其中我有外键索引,以及包含这些外键的聚簇索引。例如,我有一个如下表:
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 关于索引的行为感兴趣。
答案 0 :(得分:6)
简答 删除较短的索引。
Long Anwser 需要考虑的事项:
放弃它:
INDEX
都是一个独立的BTree,驻留在磁盘上,因此占用空间。INDEX
新行或INSERT
修改索引列时,每个UPDATE
都会更新(迟早)。这需要一些CPU和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 indexes和index cookbook的博客中更多讨论。