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"?
上的索引(ProfileID, Text)(以该顺序)是一个索引ProfileID,以及.
ProfileID如果您希望SELECT在不涉及的查询上获得更高的性能,您可能仍希望仅创建其他索引Text.
但是,这有两个缺点:
维护两个指标需要更多的资源和性能DML查询(INSERT,UPDATE,DELETE)可能会受到影响
如果混合使用这两种类型的查询,则两个索引都将占用缓存,并且可能存在比单个索引更多的缓存未命中.
如果您的表足够小以适应缓存以及两个索引,则不会出现问题.
封面索引将是两列的哈希(或者我是否误解了封面索引)?
将以这种方式创建真正覆盖的索引:
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)