小编big*_*ief的帖子

当表上有两个唯一索引且一个索引中的所有列也在另一个索引中时,是否会造成性能损失?

在我的数据库中,我有一个带有两个索引的表。出于数据完整性原因,a、b 列上有一个唯一索引 #1。我有另一个索引 #2,其中包含 c、a、b 列,用于性能原因。我注意到这个索引#2 也是唯一的。

在我看来,索引#2 的唯一性似乎是多余的,因为索引#2 中不可能有重复值,而索引#1 中也不可能有重复值。我很想更改索引 #2,使其不再唯一,因为我想象数据库引擎可能会对索引 #2 中的 c、a、b 执行第二次检查,以确保每次插入行时这些列的唯一性,从而导致即使永远不会有重复的值,也会影响性能。它是否正确?

有没有办法删除 a、b 上的索引 #1 并保留 c、a、b 上的索引 #2,但仍然只对 a、b 列施加唯一约束,而不维护两个单独的索引?这将允许我只有一个索引包含所有三列,但仍然对 a、b 强制执行数据完整性约束。为了提高性能,我不需要在 a、b 上建立索引,因为我所有的选择查询都在 where 子句中包含 c 列。这是否是唯一约束而不是索引的用例?我认为数据库引擎基本上以相同的方式对待这两个构造(请参阅这篇文章:何时应该使用唯一约束而不是唯一索引?)。

请记住,索引不是冗余的,但索引的“唯一性”是冗余的。看起来让索引 #2 变得不唯一是理所当然的。但这会带来任何实际的性能提升吗?即使索引 #1 中的列完全包含在索引 #2 中,数据库是否检查两个索引的唯一性?

一些答案询问了用于从此表中选择数据的示例查询。以下是最常见的:

Select [some other columns] from table where c=1 and a=2
Select [some other columns] from table where c=1
Select [some other columns] from table where c=1 and a=2 and b=3
Run Code Online (Sandbox Code Playgroud)

这些查询通常包括选择不在任何索引中的许多其他列。

我们通常不会运行这样的查询:

Select [stuff] from table …
Run Code Online (Sandbox Code Playgroud)

sql-server index-tuning unique-constraint

9
推荐指数
1
解决办法
1608
查看次数

为什么删除冗余索引会导致应用程序意外执行?

我继承了一个多年前由软件供应商安装的应用程序(以及相关的 MS SQL 数据库)。目前我们没有任何类型的供应商支持。除了使用应用程序之外,我们还独立于应用程序访问数据库,通常直接更新数据库并查询数据以进行报告。

为了提高性能,我删除了一些不必要的索引并创建了其他索引。当应用程序执行某些任务时,这会导致应用程序出现错误。应用程序不会显示任何类型的错误消息,并且似乎执行正常,但应用程序未按预期更新数据库。我无法访问源代码。

我的理论是,应用程序在其查询之一的 with(index) 语句中显式指定已删除的索引。这将导致服务器返回错误而不是完成查询,并且如果应用程序抑制错误,用户将不会意识到某些表已更新而其他表未更新。还有哪些其他想法可能导致这种行为?

假设我的理论是正确的,我仍然相信索引实际上是不必要的,并且应用程序不应该指定索引。也许解决方法是创建一个具有相同名称的新索引,但列数尽可能少。有没有办法创建没有列的索引?创建与聚集索引具有相同列的非聚集索引是否是最有效的?在这种情况下,优化器会做什么 - 它是否仍然制定计划包含这些仅引用聚集索引的“坏”索引,或者它会知道忽略 with(index) 请求吗?

我确实运行了跟踪来查看应用程序正在运行哪些查询。我收到了一堆 RPC 调用,例如“exec sp_cursorfetch”和“exec sp_cursorexecute”(我不明白),而不是实际的 SQL。也许我会在一个单独的问题中询问这些问题,但如果你知道我如何将这些语句解释或解码为常规 SQL,那么这至少可以让我证实我的理论。

index sql-server

1
推荐指数
1
解决办法
340
查看次数