何时在SQL Server中使用复合索引和覆盖索引?

5

我有两个表tb_player1tb_player2

CREATE TABLE tb_player1 
(
    pk_id INT PRIMARY KEY IDENTITY (1,1) NOT NULL,
    first_name CHAR(16),
    last_name CHAR(16),
    age INT
)

CREATE NONCLUSTERED INDEX ix_nonclustered_name ON tb_player1(first_name, last_name)

CREATE TABLE tb_player2 
(
    pk_id INT PRIMARY KEY IDENTITY (1,1) NOT NULL,
    first_name CHAR(16),
    last_name CHAR(16),
    age INT
)

CREATE NONCLUSTERED INDEX ix_nonclustered_name ON tb_player2(first_name)
INCLUDE (last_name)

tb_player1有一个组合索引,而tb_player2有包含列(覆盖索引)。

我对tb_player1tb_player2运行了以下SQL语句,但是tb_player1tb_player2的实际执行计划是相同的。

INSERT INTO tb_player1 VALUES('kenny', 'lee', 29)
INSERT INTO tb_player1 VALUES('rose', 'chao', 27)
INSERT INTO tb_player1 VALUES('mark', 'chao', 25)

INSERT INTO tb_player2 VALUES('kenny', 'lee', 29)
INSERT INTO tb_player2 VALUES('rose', 'chao', 27)
INSERT INTO tb_player2 VALUES('mark', 'chao', 25)



select first_name, last_name from tb_player1 where first_name = 'kenny'
select first_name, last_name from tb_player2 where first_name = 'kenny'

select first_name, last_name from tb_player1 where last_name = 'lee'
select first_name, last_name from tb_player2 where last_name = 'lee'

select first_name, last_name from tb_player1 where first_name = 'kenny' AND last_name = 'lee'
select first_name, last_name from tb_player2 where first_name = 'kenny' AND last_name = 'lee'

select first_name, last_name from tb_player2 where last_name = 'lee' AND  first_name = 'kenny'
select first_name, last_name from tb_player1 where last_name = 'lee' AND  first_name = 'kenny'

何时在SQL Server中使用复合索引和覆盖索引?它们之间有什么区别?为什么它们的执行计划看起来没有任何不同。


1
http://stackoverflow.com/questions/1589818/a-covered-index-formed-by-a-composite-index-or-index-with-included-columns - Deepak Mishra
1
@Kenny_Lee,这些计划并不完全相同。如果你看一下最后两个示例中的索引查找操作,你会发现第一个查询在 firstname 和 lastname 上进行查找,而第二个查询仅在 firstname 上进行查找。在你的情况下,这并不重要,因为你只有很少的行,但如果你有大量匹配的行,这可能会产生影响。 - Steve Ford
1个回答

6
  1. 复合索引(所有列都是“关键字”列)将在索引的所有级别中承载数据;INCLUDE索引仅在叶节点中承载“非关键字”列。 结论:与等效的复合索引相比,包含索引将更小。

  2. INCLUDE列(非关键字)不会计入最大索引大小(900字节)。

  3. 在INCLUDE索引中对非关键字列进行更新不会导致索引碎片化; 在复合索引中对未使用的“关键字”列进行更新将导致碎片化... 在我看来,这是一个重要点。

  4. 假设索引碎片化较低,则复合索引和INCLUDE索引的性能将表现得相当。查询谓词中并不需要复合索引中的所有列。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接