【问题标题】:Why better isolation level means better performance in SQL Server为什么更好的隔离级别意味着更好的 SQL Server 性能
【发布时间】:2011-01-27 21:25:29
【问题描述】:

在测量查询的性能时,我发现了隔离级别和运行时间之间的依赖关系,这让我很惊讶

READUNCOMMITTED - 409024
READCOMMITTED - 368021
REPEATABLEREAD - 358019
SERIALIZABLE - 348019

左列是表提示,右列是以微秒为单位的经过时间(sys.dm_exec_query_stats.total_elapsed_time)。为什么更好的隔离级别可以提供更好的性能?这是一台开发机器,不会发生任何并发。由于锁定开销较少,我希望 READUNCOMMITTED 是禁食的。

更新:我确实用

测量了这个
DBCC DROPCLEANBUFFERS 
DBCC FREEPROCCACHE  

已发布,Profiler 确认没有发生缓存命中。

【问题讨论】:

  • 我确实有这样的习惯,谢谢提醒。 Remus 提供了非常有价值的意见,但我仍然希望了解我观察到的现象发生的原因。

标签: sql-server optimization isolation-level


【解决方案1】:

首先,您需要在每个隔离级别下重复运行查询并将结果平均,丢弃时间最长的那个。这将消除缓冲区预热的影响:您希望所有运行都在一个热缓存上,而不是让一个查询预热缓存并支付惩罚。

接下来,您需要确保在现实的并发场景下进行测量。如果您将在现实生活中发生更新/插入/删除,那么您必须将它们添加到您的测试中,因为它们会极大地影响各种隔离级别下的读取。您最不想做的就是得出结论“可序列化读取是最快的,让我们在任何地方都使用它们”,然后看着系统在生产中崩溃,因为一切都是序列化的。

除此之外,唯一合法更快的隔离级别是脏读,因为它不获取锁。读取提交的快照(您没有测量)也不会获取锁,但由于行版本控制开销,它确实会影响整体性能。

【讨论】:

  • 请查找我的问题的更新,以解决您回复中的一些要点。 “脏读”是指 READUNCOMMITTED,对吧?
  • 1) 在冷缓存上运行查询不准确。您的生产查询不会在冷缓存上运行,您将优化一个不切实际的场景并且您不测量查询,您实际上是在测量磁盘读取吞吐量。您还需要测量热缓存的性能,并跟踪两者(冷运行时间、热运行时间)。 2) 脏读未提交。
  • 对于在正常情况下只针对特定数据运行一次的大型查询(数百万行),缓存的相关性如何?
  • 仍然非常相关。即使数据太大以至于它永远无法放入内存并且每次运行都必须重新读取表的每一页,仍然存在非叶页的缓存(即表中的热页,根或接近根),较窄的非聚集索引的缓存,表元数据的缓存。不要将您的餐桌视为 ISAM 文件。
  • 我无法理解 - ISAM 文件不是也缓存在 RAM 中吗?
【解决方案2】:

现在我更好地理解了隔离级别,我发现更好的隔离级别可以进行一些智能优化。例如,一旦事务读取某个数据隔离级别可能会规定它应该使用该数据直到结束,而不是尝试从磁盘重新读取它们。

我仍然有兴趣阅读对此的深入了解。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 2010-09-11
    • 1970-01-01
    相关资源
    最近更新 更多