我有一个有关SQL Server索引的最佳实践的问题(或任何RDBMS中的索引)。拿下表:

ProfileID int
Text      nvarchar(50)

ProfileID 加入 Profile 桌子。对于每个配置文件,每个配置文件 Text 必须是唯一的。因此,我在两列上都放了一个主封面键。美好的。

但是,我也希望能够通过 ProfileID. 。所以我也在 ProfileID 也。

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

编辑:

我以顺序创建了索引 (ProfileID, Text). 。如果出于争论的缘故,有3列A,B和C,在所有3中都有封面索引3。仅当我们与“ A”或“ A”或“ A,B和C”询问时,该怎么办“ B”或“ C”或“ B和C”?

有帮助吗?

解决方案

索引打开 (ProfileID, Text) (按此顺序)是一个索引 ProfileID 也是。

您可能仍然想在 ProfileID 仅如果您想更大 SELECT 不涉及的查询性能 Text.

但是,这有两个缺点:

  1. 维护两个索引需要更多的资源和性能 DML 查询(INSERT, UPDATE, DELETE)可能会受苦

  2. 如果将两种类型的查询混合在一起,则两个索引都将占据缓存,并且比单个索引可能会有更多的缓存错过。

    如果您的表格足够小,可以与两个索引一起放入缓存,这不是问题。

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

真正的覆盖索引将被创建:

CREATE INDEX ix_mytable_profile__text ON mytable (ProfileID) INCLUDE (Text)

这边走, Text 仅存储在索引的叶级节点中。

但是,由于您需要一个 UNIQUE 索引,这两列都必须是钥匙的一部分。节点在词典上分类 ProfileID 然后 Text.

我以顺序创建了索引(profileId,text)。如果出于争论的缘故,有3列A,B和C,在所有3中都有封面索引3。仅当我们与“ A”或“ 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).
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top