SQL Server中覆盖和单个索引的重叠

Iam*_*mIC 3 sql-server indexing covering-index

我有一个关于SQL Server(或任何RDBMS)索引的最佳实践的问题.请看下表:

ProfileID int
Text      nvarchar(50)
Run Code Online (Sandbox Code Playgroud)

ProfileID加入一张Profile桌子.每个配置文件都Text必须是唯一的.因此,我在两个列上都放置了一个主要封面键.精细.

但是,我也希望能够通过查询上表ProfileID.所以我也提了一个索引ProfileID.

这意味着我有一个重叠索引.我不知道这是否完全浪费,因为已经有一个封面索引,或者它是否正确,因为封面索引将是两列的散列(或者我是否误解了封面索引)?

编辑:

我按顺序创建了索引(ProfileID, Text).如果,为了论证的缘故,有3列A,B和C,它们都覆盖了所有3的覆盖索引.如果我们查询"A"或"A,B和C",它只会受益,但不会"B",或"C",或"B和C"?

Qua*_*noi 5

上的索引(ProfileID, Text)(以该顺序)是一个索引ProfileID,以及.

ProfileID如果您希望SELECT在不涉及的查询上获得更高的性能,您可能仍希望仅创建其他索引Text.

但是,这有两个缺点:

  1. 维护两个指标需要更多的资源和性能DML查询(INSERT,UPDATE,DELETE)可能会受到影响

  2. 如果混合使用这两种类型的查询,则两个索引都将占用缓存,并且可能存在比单个索引更多的缓存未命中.

    如果您的表足够小以适应缓存以及两个索引,则不会出现问题.

封面索引将是两列的哈希(或者我是否误解了封面索引)?

将以这种方式创建真正覆盖的索引:

CREATE INDEX ix_mytable_profile__text ON mytable (ProfileID) INCLUDE (Text)
Run Code Online (Sandbox Code Playgroud)

这样,Text只会存储在索引的叶级节点中.

但是,由于您需要UNIQUE索引,因此两列都必须是键的一部分.这些节点上的字典顺序进行排序ProfileID,然后Text.

我按顺序创建了索引(ProfileID,Text).如果,为了论证的缘故,有3列A,B和C,它们都覆盖了所有3的覆盖索引.如果我们查询"A"或"A,B和C",它只会受益,但不会"B",或"C",或"B和C"?

CREATE INDEX ix_mytable_a_b_c ON mytable (a, b, c)

SELECT  a, b, ?
FROM    mytable
WHERE   a = 1 

-- Index lookup, no table lookup. a is leading

SELECT  a, b, ?
FROM    mytable
WHERE   a = 1
        AND b = 1

-- Index lookup, no table lookup. (a, b) are leading.

SELECT  a, b, ?
FROM    mytable
WHERE   b = 1

-- Index full scan (`b` is not leading), no table lookup

SELECT  a, b, ?
FROM    mytable
WHERE   c = 1

-- Index full scan (`c` is not leading), no table lookup

SELECT  a, b, ?, d
FROM    mytable
WHERE   a = 1

-- Index lookup, table tookup (d is not a part of the index).

SELECT  a, b, ?, d
FROM    mytable
WHERE   b = 1

-- Table full scan (there is no point in using index at all, neither for lookup nor for covering).
Run Code Online (Sandbox Code Playgroud)

  • @IanC:http://msdn.microsoft.com/en-us/library/ms188783.aspx并查看"G`部分.至于我,它很清楚. (2认同)