(ProfileID, Text) 上的索引(按此顺序)也是ProfileID 上的索引。
如果您希望在不涉及Text 的查询上获得更高的SELECT 性能,您可能仍希望仅在ProfileID 上创建附加索引。
但是,这有两个缺点:
-
维护两个索引需要更多资源,DML 查询(INSERT、UPDATE、DELETE)的性能可能会受到影响
-
如果混合使用两种类型的查询,两种索引都会占用缓存,并且缓存未命中率可能比单个索引更多。
如果您的表足够小以与两个索引一起放入缓存中,这不是问题。
封面索引将是两列的哈希(或者我误解了封面索引)?
一个真正的覆盖索引将以这种方式创建:
CREATE INDEX ix_mytable_profile__text ON mytable (ProfileID) INCLUDE (Text)
这样,Text 将只存储在索引的叶级节点中。
但是,由于您需要一个 UNIQUE 索引,因此两列都需要是键的一部分。节点按字典顺序排列在ProfileID 然后Text。
我按顺序(ProfileID,文本)创建了索引。如果为了论证的缘故,有 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).