索引对更新列不在索引中的更新语句的影响


16

我经常看到人们说索引变慢updatedelete并且insert。这用作一揽子声明,就好像它是绝对的一样。

在调整数据库以提高性能的同时,我不断遇到这种情况,这种情况似乎在逻辑上对我来说与该规则相矛盾,而且我在任何地方都找不到其他方式可以说或解释的人。

在SQL Server中,并且我相信/假定将使用大多数其他DBMS,您的索引是根据您指定的特定列创建的。插入和删除将始终影响整个行,因此没有办法不会影响索引,但是更新似乎更加独特,它们可以专门影响某些列。

如果我有未包含在任何索引中的列并更新了它们,它们是否会因为我在该表中的其他列上有索引而放慢了速度?

例如,在我的User表中,我有一个或两个索引,主键是Identity / Auto Increment列,外键列上可能还有另一个。
如果我更新没有索引直接在其上的列(例如说他们的电话号码或地址),由于在任何一种情况下我在该表的其他列上都有索引,此更新是否会变慢?我要更新的列不在索引中,因此从逻辑上讲,不应更新索引,不是吗?如果有的话,如果我使用WHERE子句中的索引,我认为它们会加快速度。


so there is no way they will not affect the index除了过滤索引...
usr

我认为未覆盖的非聚集索引包含指向记录的指针(通常在表的聚集索引叶节点中)。我认为一种导致UPDATE期间(不包含属性的)速度变慢的情况可能是UPDATE导致记录在聚簇索引内移动的情况。我仍然不确定移动是否会导致指针发生变化,或者指针是否只是聚簇索引中的KEY值,在这种情况下,可能的位置更新并不重要,因为系统只会执行KEY查找获取记录值。
Jmoney38年

Answers:


6

您是正确的,更新未编制索引的列不会导致更改索引。在简单的情况下,也不会对桌子产生整体影响。

如果查询可以使用索引查找数据,则可以加快查找速度,但是确切的行为(取决于您的SQL品牌)可能与其他SQL品牌不同。(我主要使用Microsoft SQL Server。)

当然,更新具有大量数据的列可能会导致某些行移动到其他页面等。


1
在OP中提到了SQL Server,我添加了一个标记,因此我认为您可以假定SQL Server
Tom V-Team Monica

10

对于相对较快的现代系统,从绝大多数系统的性能角度来看,向 OLTP表中添加单个索引可能实际上是不可检测。就是说,您不应该创建不必要的索引,并且可能不应该为表中的每个列创建单列索引。

您的假设是正确的,因为对于许多查询,有用索引的存在将导致非常明显的速度改进。

尽管您的问题似乎与性能有关,但是在添加索引方面还有其他一些潜在问题,包括但不限于:

  1. 将索引添加到表时,创建索引所需的时间可能会导致阻塞。锁的寿命很短,很可能不会造成大问题。

  2. 索引更改导致执行计划对于引用该基础表的任何计划均无效。重新编译这些执行计划时,某些查询的性能可能会发生负面变化。

  3. 索引修改可能会导致查询返回错误,而先前未返回任何错误。以过滤索引为例,该索引用于返回varchar字段中包含的日期;如果过滤器消除了所有非日期的行,并且该过滤器随后进行了更改,则在尝试转换非日期数据时,依赖于该索引的查询现在可能会失败。

  4. 新索引可能会导致执行顺序发生更改,从而可能导致死锁发生,而以前从未发生过。


“仍然需要评估在不影响索引时更新所需的代码路径”,这是不正确的。编译/优化阶段将非常了解需要更新哪些索引(如果有),并将相应地创建计划。不会修改(在SET列表中声明)索引中的列(包括INCLUDE和集群键列)的UPDATE语句将不必更新该索引,并且执行阶段甚至不会触及它。显然,DELETE和INSERT会(逻辑上)触及所有列,并且必须更新所有索引。
Remus Rusanu'1

@RemusRusanu,但是如果可以使用索引来查找需要更新的行,就不需要评估它吗?
汤姆五世-莫妮卡团队

@RemusRusanu-我想一旦QO制定了计划,就不再需要CPU;但是要制定计划,肯定需要这样做。如果计划经常被编译,可能会产生很小的变化。
Max Vernon

@TomV使用索引来定位删除/更新候选行是一个完全不同的主题。如果是这种情况,那么通过索引定位行的优势应该压倒了任何索引维护成本的问题。
Remus Rusanu'1

@MaxVernon我认为没有正确的DML频繁重新编译(更新)方案。我购买某些情况下的有效(不可避免的)重新编译以进行临时查询。但是DML?什么样的应用程序可以创建临时的,独特的UPDATE语句?使用DML的频繁重新编译会大声喊出“参数化我”。
Remus Rusanu

-2

如果更新操作的目标是固定大小(如整数)的非索引列,那么一般来讲它应该不会慢,但与select语句相比,更新最终也必须写入慢速磁盘。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.