Rya*_*yan 18 performance index sql-server update query-performance
我经常看到人们说索引变慢了update
,delete
并且insert
。这被用作笼统的陈述,就好像它是绝对的一样。
在调整我的数据库以提高性能的同时,我不断遇到这种情况,这对我来说在逻辑上似乎与该规则相矛盾,而且我找不到任何人以其他方式说或解释。
在 SQL Server 中,我相信/假定大多数其他 DBMS,您的索引是根据您指定的特定列创建的。插入和删除总是会影响整行,因此它们不可能不影响索引,但更新似乎更独特一些,它们只能专门影响某些列。
如果我有未包含在任何索引中的列并且我更新它们,它们是否会因为我在该表中的其他列上有索引而变慢?
例如,在我的User
表中,我有一个或两个索引,主键是 Identity/Auto Increment 列,另一个可能是某个外键列。
如果我直接更新一个没有索引的列,比如他们的电话号码或地址,这个更新是否会变慢,因为我在这两种情况下的其他列上都有索引?我正在更新的列不在索引中,所以从逻辑上讲,索引不应该更新,不是吗?如果有的话,我认为如果我在 WHERE 子句中使用索引,它们会加速。
Han*_*non 10
对于相对较快的现代系统,从性能的角度来看,对于绝大多数系统来说,向 OLTP 表添加单个索引可能几乎无法检测到。也就是说,您不应该创建不必要的索引,并且您可能不应该为表中的每一列创建单列索引。
您的假设是正确的,对于许多查询,有用索引的存在将导致非常显着的速度提高。
尽管您的问题似乎与性能有关,但添加索引还存在其他几个潜在问题,包括但不限于:
创建索引所需的时间可能会导致在将索引添加到表时发生阻塞。锁的寿命很短,很可能不会造成大问题。
索引更改导致任何引用基础表的计划的执行计划无效。当重新编译这些执行计划时,某些查询的性能可能会发生负面变化。
索引修改可能导致查询返回错误,而之前没有返回错误。以用于返回包含在 varchar 字段中的日期的过滤索引为例;如果过滤器消除了任何不是日期的行,并且随后更改了该过滤器,则在尝试转换非日期数据时依赖于该索引的查询现在可能会失败。
新索引可能会导致执行顺序发生变化,从而导致可能在之前未发生的地方发生死锁。
您是正确的,更新非索引列不会导致索引更改。在一个简单的情况下,也不会对表产生整体影响。
如果查询可以使用索引来查找数据,它可能会加快查找速度,但确切的行为(取决于您的 SQL 品牌)可能与其他品牌的 SQL 不同。(我主要使用 Microsoft SQL Server。)
当然,更新具有大量数据的列可能会导致某些行移动到不同的页面等。