什么是 MySQL 覆盖索引?
What is a MySQL covering index?
我看到documentation描述覆盖指数:
covering index
An index that includes all the columns retrieved by a query.
覆盖索引是不是特定索引?
我觉得覆盖指数是一种现象
如果我按照文档的描述,那么请看下面的sql声明:
create index idx_name_age on table(id, name)
select id, name from table where id = 1
select id, name, age from table where id = 1
idx_name_age
是第一个语句中的覆盖索引,第二个不是。
所以我认为:覆盖指数是一种现象而不是一个指数。
is the covering index is a specific index?
是的,它是专门为满足特定查询而设计的索引。
对于这个查询
select id, name, age from table where id = 1
覆盖索引是 (id, name, age)
上的多列索引,由
创建
create index idx_name_age on table(id, name, age)
怎么会这样?
id
是索引中的第一列,因为它在 WHERE id = 1
中使用。首先是因为 MySQL 索引通常是 BTREE,可以按索引顺序随机访问。所以 WHERE id = 1
可以在索引中跳转以找到那些 id
值。
name
和 age
也出现在索引中,因为它们出现在 SELECT
子句中。因为它们在索引中,查询可以完全从索引中得到满足。这很好,因为它减少了从磁盘或 ssd 的读取:MySQL 没有在满足查询之前使用索引在主 table 中查找行。
仅 (id, name)
上的索引 不是 上述查询的覆盖索引; age
列缺失。
这个查询
select id, name from table where id = 1
也可以从(id, name, age)
覆盖索引满足。它也可以通过(id, name)
上的索引满足:是覆盖索引对于第二个查询(但不是第一个)。
您的示例说明了词汇表的定义。索引通过使用额外的 disk/ssd space 来存储数据来提高查询性能。
Microsoft SQL 服务器用户可以这样声明索引:
create index idx_name_age on table (id) include (name, age)
在此索引中,name
和 age
的值与索引中的 id
并存,但索引未按包含的列排序。因此,更新索引花费的时间更少。
如果 id
是 table 的主键,则 none 适用于 MySQL 的 InnoDB 或 SQL 服务器。 table 本身是 id
上的索引;它有时被称为聚簇索引。但是现在我们涉及的细节太多了。
如果使用得当,覆盖索引可以显着 提高查询性能。阅读 https://use-the-index-luke.com/ 要获得有用的索引,您必须设计它们以匹配您的查询。这是数据库优化艺术的很大一部分。
假设 "covering" 是特定 SELECT
的索引 相对 的 属性 。
一些示例:
select id, name from table where id = 1
INDEX(id, name) -- covering; best index
INDEX(id, name, age) -- covering, but overkill
INDEX(age, name, id) -- covering, but inefficient (might not be used)
select id, name, age from table where id = 1
INDEX(id, name, age) -- Having `id` first is optimal, but any order is "covering"
正如已经指出的那样,如果这是 InnoDB 并且 table 有 PRIMARY KEY(id)
,那么这些二级索引中的 none 是值得拥有的。
SELECT a FROM tbl GROUP BY b ORDER BY c
No index is very useful since the GROUP BY and ORDER BY are not the same.
INDEX(a,b,c) -- in any order, is "covering"
INDEX(b,c,a) -- "covering", and perhaps optimal.
INDEX(b,c,a,d) -- "covering", but 'bigger'
大事小事。当执行 SELECT COUNT(*) FROM ...
时,InnoDB 将(通常)选择 'smallest' 索引来进行计数。
另一个'rule'是为了避免冗余索引。
INDEX(a,b) -- Let's say you 'need' this one.
INDEX(a) -- Then this one is redundant and should be dropped.
我看到documentation描述覆盖指数:
covering index
An index that includes all the columns retrieved by a query.
覆盖索引是不是特定索引?
我觉得覆盖指数是一种现象
如果我按照文档的描述,那么请看下面的sql声明:
create index idx_name_age on table(id, name)
select id, name from table where id = 1
select id, name, age from table where id = 1
idx_name_age
是第一个语句中的覆盖索引,第二个不是。
所以我认为:覆盖指数是一种现象而不是一个指数。
is the covering index is a specific index?
是的,它是专门为满足特定查询而设计的索引。
对于这个查询
select id, name, age from table where id = 1
覆盖索引是 (id, name, age)
上的多列索引,由
create index idx_name_age on table(id, name, age)
怎么会这样?
id
是索引中的第一列,因为它在 WHERE id = 1
中使用。首先是因为 MySQL 索引通常是 BTREE,可以按索引顺序随机访问。所以 WHERE id = 1
可以在索引中跳转以找到那些 id
值。
name
和 age
也出现在索引中,因为它们出现在 SELECT
子句中。因为它们在索引中,查询可以完全从索引中得到满足。这很好,因为它减少了从磁盘或 ssd 的读取:MySQL 没有在满足查询之前使用索引在主 table 中查找行。
仅 (id, name)
上的索引 不是 上述查询的覆盖索引; age
列缺失。
这个查询
select id, name from table where id = 1
也可以从(id, name, age)
覆盖索引满足。它也可以通过(id, name)
上的索引满足:是覆盖索引对于第二个查询(但不是第一个)。
您的示例说明了词汇表的定义。索引通过使用额外的 disk/ssd space 来存储数据来提高查询性能。
Microsoft SQL 服务器用户可以这样声明索引:
create index idx_name_age on table (id) include (name, age)
在此索引中,name
和 age
的值与索引中的 id
并存,但索引未按包含的列排序。因此,更新索引花费的时间更少。
如果 id
是 table 的主键,则 none 适用于 MySQL 的 InnoDB 或 SQL 服务器。 table 本身是 id
上的索引;它有时被称为聚簇索引。但是现在我们涉及的细节太多了。
如果使用得当,覆盖索引可以显着 提高查询性能。阅读 https://use-the-index-luke.com/ 要获得有用的索引,您必须设计它们以匹配您的查询。这是数据库优化艺术的很大一部分。
假设 "covering" 是特定 SELECT
的索引 相对 的 属性 。
一些示例:
select id, name from table where id = 1
INDEX(id, name) -- covering; best index
INDEX(id, name, age) -- covering, but overkill
INDEX(age, name, id) -- covering, but inefficient (might not be used)
select id, name, age from table where id = 1
INDEX(id, name, age) -- Having `id` first is optimal, but any order is "covering"
正如已经指出的那样,如果这是 InnoDB 并且 table 有 PRIMARY KEY(id)
,那么这些二级索引中的 none 是值得拥有的。
SELECT a FROM tbl GROUP BY b ORDER BY c
No index is very useful since the GROUP BY and ORDER BY are not the same.
INDEX(a,b,c) -- in any order, is "covering"
INDEX(b,c,a) -- "covering", and perhaps optimal.
INDEX(b,c,a,d) -- "covering", but 'bigger'
大事小事。当执行 SELECT COUNT(*) FROM ...
时,InnoDB 将(通常)选择 'smallest' 索引来进行计数。
另一个'rule'是为了避免冗余索引。
INDEX(a,b) -- Let's say you 'need' this one.
INDEX(a) -- Then this one is redundant and should be dropped.