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

Ken*_*Lee 5 t-sql sql-server indexing

我有2个表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)
Run Code Online (Sandbox Code Playgroud)

tb_player1有复合指数和tb_player2具有包括柱(覆盖索引).

我请对下面的SQL语句tb_player1tb_player2,但实际的执行计划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'
Run Code Online (Sandbox Code Playgroud)

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

Dee*_*hra 6

  1. 复合索引(其中所有列都是"关键"列)将携带索引的所有级别的数据; INCLUDE索引仅携带叶节点中的"非键"列.带走:INCLUDE索引将小于等效的复合索引.

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

  3. 对INCLUDE索引中的非键列的更新将不会导致索引碎片; 复合索引中未使用的"key"列的更新将导致碎片... IMO,这是一个很大的问题.

  4. 假设索引碎片较低,复合索引和INCLUDE索引的性能相当.复合索引中的所有列不必位于查询谓词中.