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

标签 sql-server indexing covering-index

我有一个关于在 SQL Server(或与此相关的任何 RDBMS)中建立索引的最佳实践的问题。取下表:

ProfileID int
Text      nvarchar(50)

ProfileID 连接到 Profile 表。对于每个配置文件,每个 Text 都必须是唯一的。因此,我在两列上都放置了主封面 key 。很好。

不过,我也希望能够通过ProfileID来查询上表。所以我也在 ProfileID 上加了一个索引。

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

编辑:

我按照 (ProfileID, Text) 的顺序创建了索引。如果为了论证的缘故,有 3 列 A、B 和 C,它们的覆盖索引覆盖所有 3 列。如果我们查询“A”或“A、B 和 C”而不是查询,它是否只会受益? “B”,还是“C”,还是“B 和 C”?

最佳答案

(ProfileID, Text) 上的索引(按此顺序)也是 ProfileID 上的索引。

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

但是,这有两个缺点:

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

  2. 如果您混合使用这两种类型的查询,两个索引都会占用缓存,并且缓存未命中次数可能比使用单个索引的次数多。

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

The cover index would be a hash of the two columns (or am I misunderstanding cover indexes)?

真正的覆盖索引可以这样创建:

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

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

但是,由于您需要一个 UNIQUE 索引,所以两列都需要是键的一部分。节点在 ProfileID 上按字典顺序排序,然后在 Text 上排序。

I created the index in the order (ProfileID, Text). What if, for argument's sake, there were 3 columns A, B, and C, that had a cover index over all 3. Would it only benefit if we queried against "A" or "A, B, and C", but not "B", or "C", or "B and 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).

关于sql-server - SQL Server 中覆盖和单个索引的重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4154540/

相关文章:

sql-server - 将密码存储在数据库中以备后用

mongodb - Mongo 稀疏索引未按预期工作

python - 分层索引的求和列?

database - 识别覆盖索引中不需要的列的方法有哪些?

sql-server - 我可以使用 Truecrypt 来保护 SQL 2008 数据库,以便只有我的应用程序可以看到数据吗?

sql-server - SQL Server 导出/导入序列

mysql - 什么是 MySQL 覆盖索引?

ruby-on-rails - 从 Ubuntu 中的 ROR 应用程序连接到 SQL Server 2005

matlab - 在 MATLAB 中修改时间序列数据单个值