多列上的非群集索引VS单个索引中的多个列

时间:2012-10-18 09:23:19

标签: sql-server azure-sql-database

我正在向SQL Azure DB添加非聚集索引,我想知道在单个非聚簇索引中拥有多个列之间的区别是什么,与多个非聚簇索引相比,每个索引都包含一个列?

2 个答案:

答案 0 :(得分:2)

  

在单个非聚集索引中拥有多个列之间的区别,与具有多个非聚簇索引的每个列中包含一个列相比?

考虑使用带有c T列的Id表,以及ABC列。{/ p>

包含ABC的单个非聚集索引可以支持快速查找查询,例如:

WHERE A > @a
WHERE A = @a AND @b1 < B AND B < @b2
WHERE A = @a AND B = @b AND C < @c

但不是

WHERE B = @b
WHERE C = @c

在这两种情况下,我们都不能比表扫描做得更好

但是,如果我们在IX_A上有多个索引A,等等:

WHERE A = @a
WHERE B = @b
WHERE C = @c

将全部受益于索引和复合查询,例如

WHERE A = @a AND B = @b AND C < @c

也会带来一点好处。

答案 1 :(得分:0)

那些优化的SELECT查询是不同的。

您不应该在不需要优化查询性能的情况下添加索引。

如果您有要优化的查询,那么您可以开始考虑添加与要优化的查询相对应的索引。

假设您有一个包含以下结构的表:

create table emp
(
    id int identity primary key clustered,
    name nvarchar(200),
    dep_id int,
    salary int
);

您的聚集索引(primary key clustered子句)将使用id列作为过滤器的查询加快查询和行数据检索:

select id, name, dep_id, salary
from emp
where id = @id

任何(唯一)列上的任何非聚集索引都将使用与筛选器相同的列来加速查找(而不是行数据检索)。

create index emp_name_idx on emp(name);
-- will speed up look-up for 
select id, dep_id
from emp
where name = @name

如果您还想使用相同的索引加速行数据检索,则需要将SELECT子句中的列添加到包含的列中。

create index emp_name_idx on emp(name) include(id, dep_id);
-- will speed up look-up and data row retrieval for 
select id, dep_id
from emp
where name = @name

任何包含多列的非聚集索引都会加快查询,使用前n列的查询,它们与索引中出现的顺序相同(只要过滤器是相等比较,列优化条纹将结束为第一次不平等比较得到满足。

create index emp_namesalary_idx on emp(dep_id, salary);
-- will speed up look-up and data row retrieval for 
select id, dep_id
from emp
where dep_id = @dep_id
  and salary > @salary

对于单列索引,为了优化行数据检索,请使用include子句指定SELECT子句中尚未出现在索引列列表中的每一列。

请记住,对于添加到表中的每个索引,您还要为此表添加INSERT开销。因此,您应该始终平衡SELECT语句上的索引和INSERT语句上的损失之间的性能。 还要记住索引使用磁盘(和缓存)空间,这也应该在决策过程中计算。