sql-server – 声明索引在SQL Server中是唯一的

前端之家收集整理的这篇文章主要介绍了sql-server – 声明索引在SQL Server中是唯一的前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如果我知道一个索引将具有唯一的值,那么如果我这样声明就会影响插入的性能,或选择它.

如果优化器知道索引是独一无二的,会影响查询计划?

我明白指定唯一性可以有助于保持诚信,但暂时将讨论放在一边,什么是性能后果.

解决方法

长篇小说:如果您的数据本质上是独一无二的,您将受益于在其上创建一个UNIQIE索引.

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

> Making an index UNIQUE

现在,血腥细节.

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

独特指数具有最大的可能选择性,这就是为什么:

SELECT  *
FROM    table1 t2,table2 t2
WHERE   t1.id = :myid
        AND t2.unique_indexed_field = t1.value

几乎肯定会使用NESTED LOOPS,而

SELECT  *
FROM    table1 t2,table2 t2
WHERE   t1.id = :myid
        AND t2.non_unique_indexed_field = t1.value

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

如果你的索引是CLUSTERED(即它们自己被包含在索引叶中)和非UNIQUE,那么一个名为uniquifier的特殊隐藏列被添加到每个索引键中,从而使得键越大,索引越慢.

这就是为什么UNIQUE CLUSTERED指数实际上比非UNIQUE CLUSTERED指数更有效率.

在Oracle中,对于所谓的密钥保存需要对UNIQUE INDEX进行加入,这确保了表中的每一行最多被选中一次,并使视图更新.

这个查询

UPDATE  (
        SELECT  *
        FROM    mytable t1,mytable t2
        WHERE   t2.reference = t1.unique_indexed_field
        )
SET     value = other_value

将在Oracle中工作,而这一个:

UPDATE  (
        SELECT  *
        FROM    mytable t1,mytable t2
        WHERE   t2.reference = t1.non_unique_indexed_field
        )
SET     value = other_value

将失败.

这不是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)

,这个查询

/* Sorts on the non-unique index first */
SELECT  TOP 1 *
FROM    t_indexer
ORDER BY
        ival,uval

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

/* Sorts on the unique index first */
SELECT  TOP 1 *
FROM    t_indexer
ORDER BY
        uval,ival

将只使用索引扫描.

对于后一种查询,对于ival而言,没有其他的排序,因为uval是唯一的,优化器也考虑到这一点.

在200,000行的样本数据(id == uval == ival)上,前一个查询运行了15秒,后一个是即时.

原文链接:https://www.f2er.com/mssql/82915.html

猜你在找的MsSQL相关文章