21

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

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

我知道指定唯一性可以保持完整性,但暂时搁置讨论,性能后果是什么。

4

6 回答 6

26

长话短说:如果您的数据本质上是UNIQUE,您将从为UNIQIE它们创建索引中受益。

详细解释见我博客中的文章:


现在,血腥的细节。

正如@Mehrdad所说,UNIQUENESS会影响计划生成器中的估计行数。

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

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

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

将在 中工作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几秒钟,而后一个查询是即时的。

于 2009-04-16T12:07:37.640 回答
4

当然,优化器会考虑唯一性。它会影响查询计划中的预期行数。

于 2009-04-16T10:18:42.053 回答
1

插入数据时性能会受到负面影响。它需要检查唯一性。

于 2009-04-16T10:55:16.287 回答
1

我刚刚在我的机器上测试了一个包含超过 100 万行的生产表,因为我认为这是一个很好的测试。结果很有趣,这是原始数字:

-- 无索引:

    Setup Time: 8888, Insert Time: 501690

-- 唯一约束:

    Setup Time:   42, Insert Time: 488030

设置包括获取我添加唯一约束的字段的最大值 - 因此从逻辑上讲,通过添加约束可以显着提高性能。当通过这个外键搜索时,这也将提高性能。

有趣的是,插入时间也略有改善(提高了 2.7228%),因此只有添加约束(+ 固有索引)的积极影响 [在我的测试用例中]。

测试仅显示添加约束的积极影响 - 没有性能影响。

注意:对于我们的测试系统,我希望这些值几乎总是唯一的,所以我没有测试插入非唯一值,在这个数据中它确实是一个例外 - 而不是我们需要高性能的东西。

于 2014-04-15T04:53:56.630 回答
0

是的,它会被查询引擎考虑在内。

于 2009-04-16T10:28:40.657 回答
0

也许更重要的是:唯一性将保护数据的完整性。性能将有理由忽略这一点。

性能可能会受到正面或负面影响或根本不受影响:这取决于查询,是否使用索引等

于 2009-04-16T10:28:55.147 回答