首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >复合指标的开销

问复合指标的开销
EN

Stack Overflow用户
提问于 2015-09-06 00:10:33
回答 1查看 1K关注 0票数 8

我有许多表,其中有外键的索引,还有包含这些外键的聚集索引。例如,我有一个表,如下所示:

代码语言:javascript
复制
TABLE: Item
------------------------
id       PRIMARY KEY
owner    FOREIGN KEY
status

... many more columns

MySQL为主键和外键生成索引,但有时我希望提高查询性能,以便创建聚集索引或覆盖索引。这将导致具有重叠列的索引。

代码语言:javascript
复制
INDEXES ON: Item
------------------------
idx_owner (owner)
idx_owner_status (owner, status)

如果我删除了idx_owner,以后通常使用idx_owner的查询只会使用idx_owner_status,因为它将owner作为索引中的第一列。

值得把idx_owner留在身边吗?是否有额外的I/O开销可以使用idx_owner_status,即使MySQL只使用部分索引?

编辑:我真正感兴趣的只是InnoDB对索引的行为方式。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-06 00:50:00

短答案删除较短的索引。

Long和Anwser要考虑的事情:

放下它:

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

不要放弃:

  • 较长的指数比较短的指数大。因此,它不太容易缓存。因此(在极端情况下)使用更大的一个代替较短的一个可能会导致更多的I/O,这使情况更加恶化:INDEX(int, varchar255)。

这是非常罕见的,最后一个项目真的超过其他项目。

奖金

“覆盖”索引是包含SELECT中提到的所有列的索引。例如:

代码语言:javascript
复制
SELECT status FROM tbl WHERE owner = 123;

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

代码语言:javascript
复制
SELECT status, foo FROM tbl WHERE owner = 123;

如果确实需要更快的查询,那么将两个索引替换为INDEX(owner, status, foo)。

PK在辅助密钥中的应用

再来点小甜头..。在InnoDB中,PRIMARY KEY的列被隐式地附加到每个次要键。所以,这三个例子实际上是

代码语言:javascript
复制
INDEX(owner, id)
INDEX(owner, status, id)
INDEX(owner, status, foo, id)

更多讨论在我的博客在http://mysql.rjweb.org/doc.php/index1和http://mysql.rjweb.org/doc.php/index_cookbook_mysql上。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32418812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档