如果我有频繁的DML操作(插入、更新、删除),那么表中包含大量数据,包含聚集索引和非聚集索引。它会影响索引列上具有where条件的表上SELECT查询的性能,还是与没有DML操作时的性能相同?
这个链接说UpdateStatistics确实阻止选择查询。DML操作也会导致UpdateStatistics。它说:“只有当您的数据库中启用了AUTO_UPDATE_STATISTICS,并且AUTO_UPDATE_STATISTICS_ASYNC被禁用时,您才不会控制它。”那么,改变这些值是最好的解决方案吗?
注意:对于SELECT查询,我将使用隔离级别(读未提交),该查询不应被锁阻止。
发布于 2020-12-14 10:43:31
首先,对术语进行评论: DML (数据操作语言)包括SELECT。我有种感觉,当你说DML是指插入,更新和删除。我将把这些称为“修改声明”。
您还会说您运行“默认隔离级别(读取未提交)”。那是不对的。默认隔离级别是“已提交读取”,而不是“未提交读取”。
通过数据修改语句获得的独占锁确实阻止了提交的读。这是的默认行为,但是您可以通过将Read快照更改为ON (RCSI)来重新配置该行为。使用RCSI读取器不会被修饰符阻塞,他们将得到最后提交的行版本,而不是等待。(默认情况下,对于Azure SQL数据库,RCSI是ON的。)
不要担心更新统计数据。它不会阻止读者。在更新统计信息的同时,您所引用的索引重组的博客文章。本身不会阻止读者。
发布于 2020-12-14 03:59:15
*注意,这个答案从默认的隔离级别开始,这是OP最初询问的,但随后进入了他所好奇的实际隔离级别。
通常,DML查询确实会导致行和表上的锁,这将影响选择性能,特别是在读提交的隔离级别。它取决于特定的DML操作、它影响的记录、选择查询以及需要读取的记录。
如果某个DML操作只导致行级锁,那么只有那些特定的行将被锁定,并且在等待释放DML锁时,针对这些行的选择将被阻塞。将不会阻止针对同一表的其他行进行的选择。如果DML操作升级到Table级锁,那么对该表的所有SELECT查询都将被阻止。请记住,大多数情况下,无论以哪种方式,这通常都是非常快速的,而不是什么问题(除非它是一个构造糟糕的DML操作)。
不管是否有索引,前面都是正确的,唯一的区别是某些DML操作可能稍微慢一些,表上存在的索引越多,比如INSERT操作。相反,其他DML操作(如更新)通常在表上的适当索引中执行得更好,因为索引帮助更新操作定位要更新的记录。
由于OP意味着它们使用的是读未提交的隔离级别,所以直接行和表级别的锁定不适用于那些通常在默认隔离级别( readers )中阻塞读取器的写入器。
但是,繁重的DML操作仍然会导致表或服务器上的争用,从而影响SELECT查询的性能。例如,如果表被压缩,单个查询中有大量行是UPDATEd,则可以使用大量的CPU和I/O,而这些服务器资源在整个操作过程中将处于争用状态,从而可能导致其他SELECT查询在该服务器上运行得更慢。
在数据库世界中,“海量数据”是非常主观的。我不知道这在数量上对您意味着什么,但我在数据库中工作过,其中的表有数百亿行,每分钟执行多个DML操作到1,000行,而且选择的性能仍然很好。
https://dba.stackexchange.com/questions/281482
复制相似问题