【问题标题】:When to use composite index and covering index in SQL Server?什么时候在 SQL Server 中使用复合索引和覆盖索引?
【发布时间】:2014-12-15 08:54:08
【问题描述】:

我有两张桌子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 有包含列(覆盖索引)。

我对@9​​87654327@和tb_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 中使用复合索引和覆盖索引?它们之间有什么区别?为什么他们的执行计划看起来没有什么不同。

【问题讨论】:

  • @Kenny_Lee 计划并不完全相同,如果您查看最后两个示例中的索引查找操作,您会看到第一个查询在 firstname 和 lastname 上查找,而第二个查询仅在 firstname 上查找.这在您的情况下并不重要,因为您的行数很少,但如果您有大量匹配行,则可能会产生影响。

标签: sql-server tsql indexing


【解决方案1】:
  1. 复合索引(所有列都是“关键”列)将承载索引所有级别的数据; INCLUDE 索引将只携带叶节点中的“非键”列。带走:INCLUDE 索引将小于等效的复合索引。

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

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

  4. 假设索引碎片较少,复合索引和 INCLUDE 索引的性能相当。复合索引中的所有列都不需要在查询谓词中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 2011-12-18
    相关资源
    最近更新 更多