我正在向 SQL Azure DB 添加非聚集索引,我想知道在单个非聚集索引中包含多个列与在每个非聚集索引中包含一个列的多个非聚集索引有什么区别?
2 回答
在单个非聚集索引中具有多个列与在其中具有多个非聚集索引且每个具有单个列之间的区别?
考虑一个T
具有聚集 PKId
列的表,以及另外的列A
、B
、C
。
包含A
、B
和的单个非聚集索引C
可以支持快速查找查询,例如:
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
onA
等:
WHERE A = @a
WHERE B = @b
WHERE C = @c
都将受益于索引和复合查询,例如
WHERE A = @a AND B = @b AND C < @c
也会有一点好处。
那些将优化的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
。还要记住,索引使用磁盘(和缓存)空间,这也应该计入决策过程。