在SQL Server中声明索引是唯一的

cin*_*ndi 21 sql-server indexing performance unique

如果我知道索引将具有唯一值,那么它将如何影响插入的性能或如果我声明它如此.

如果优化器知道索引是唯一的,那么它将如何影响查询计划?

我明白指定uniquenes可以起到保持完整性的作用,但暂时搁置这个讨论,会产生什么样的后果.

Qua*_*noi 26

简而言之:如果您的数据本质上UNIQUE,您将从中创建UNIQIE索引中受益.

有关详细说明,请参阅我博客中的文章:


现在,血淋淋的细节.

正如@Mehrdad所说,UNIQUENESS影响计划构建器中的估计行数.

UNIQUE index具有最大可能的选择性,这就是为什么:

SELECT  *
FROM    table1 t2, table2 t2
WHERE   t1.id = :myid
        AND t2.unique_indexed_field = t1.value
Run Code Online (Sandbox Code Playgroud)

几乎肯定会使用NESTED LOOPS,而

SELECT  *
FROM    table1 t2, table2 t2
WHERE   t1.id = :myid
        AND t2.non_unique_indexed_field = t1.value
Run Code Online (Sandbox Code Playgroud)

HASH JOIN如果优化器认为non_unique_indexed_field没有选择性,可能会受益于.

如果您的索引CLUSTERED(即它们自己包含在索引中的行)和非索引UNIQUE,则会uniquifier在每个索引键中添加一个特殊的隐藏列,从而使键更大,索引更慢.

这就是为什么UNIQUE CLUSTERED指数实际上比一个指数更有效率的原因non-UNIQUE CLUSTERED.

Oracle,UNIQUE INDEX这样的被调用需要连接key preservation,这确保了表中的每一行最多只能选择一次并使视图可更新.

这个查询:

UPDATE  (
        SELECT  *
        FROM    mytable t1, mytable t2
        WHERE   t2.reference = t1.unique_indexed_field
        )
SET     value = other_value
Run Code Online (Sandbox Code Playgroud)

将工作Oracle,而这一个:

UPDATE  (
        SELECT  *
        FROM    mytable t1, mytable t2
        WHERE   t2.reference = t1.non_unique_indexed_field
        )
SET     value = other_value
Run Code Online (Sandbox Code Playgroud)

将失败.

但这不是问题SQL Server.

还有一件事:对于像这样的桌子,

CREATE TABLE t_indexer (id INT NOT NULL PRIMARY KEY, uval INT NOT NULL, ival INT NOT NULL)
CREATE UNIQUE INDEX ux_indexer_ux ON t_indexer (uval)
CREATE INDEX ix_indexer_ux ON t_indexer (ival)
Run Code Online (Sandbox Code Playgroud)

,这个查询:

/* Sorts on the non-unique index first */
SELECT  TOP 1 *
FROM    t_indexer
ORDER BY
        ival, uval
Run Code Online (Sandbox Code Playgroud)

将使用a TOP N SORT,而这一个:

/* Sorts on the unique index first */
SELECT  TOP 1 *
FROM    t_indexer
ORDER BY
        uval, ival
Run Code Online (Sandbox Code Playgroud)

将仅使用索引扫描.

对于后一个查询,没有必要进行额外的排序ival,因为uval无论如何都是唯一的,并且优化器会考虑到这一点.

200,000rows(id == uval == ival)的示例数据上,前一个查询运行15秒,而后一个查询是即时的.

  • 是的,如果索引可能是唯一的,那么你当然应该使它独一无二.在本质上的UNIQUE数据上使用非UNIQUE索引没有任何好处.UNIQUE帮助SQL Server了解数据是否真正独特并优化算法. (4认同)