我有一个Kimball风格的DW(明星模型中的事实和维度 - 没有迟到的事实行或列,没有列的尺寸变化,除了到期作为类型2缓慢变化的尺寸的一部分),每天都要加工大量插入和更新行(在新日期)以及每月和每日报告流程。事实表按日期划分,以便轻松滚动旧数据。

我理解 WITH(NOLOCK)会导致读取未提交的数据,但是,我也不希望创建任何会导致ETL进程失败或阻塞的锁。

在所有情况下,当我们从DW读取数据时,我们正在从事实表中读取一个不会更改的日期(事实表按日期分区)和维度表,这些表不会因为事实而改变属性与...链接。

那么 - 有什么缺点吗? - 可能在执行计划中或在此类 SELECT 的操作中 - 仅在同一个表中并行运行的查询。

有帮助吗?

解决方案

只要它都是无更新数据就没有任何伤害,但如果有很多好处我会感到惊讶。我说这值得一试。最糟糕的情况是,如果您处于批量插入的中间,您将获得不完整和/或不一致的数据,但您可以决定是否会使任何有用的内容无效。

其他提示

这是您可能需要的:

`ALTER DATABASE AdventureWorks     SET READ_COMMITTED_SNAPSHOT ON;

ALTER DATABASE AdventureWorks     SET ALLOW_SNAPSHOT_ISOLATION ON; `

然后继续使用

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

在您的查询中

。据BOL说:

READ COMMITTED的行为取决于READ_COMMITTED_SNAPSHOT数据库选项的设置:

如果READ_COMMITTED_SNAPSHOT设置为OFF(缺省值),则数据库引擎使用共享锁来防止其他事务在当前事务运行读取操作时修改行。共享锁还会阻止语句读取由其他事务修改的行,直到另一个事务完成为止。共享锁定类型确定何时释放它。在处理下一行之前释放行锁。读取下一页时会释放页锁,并在语句结束时释放表锁。

如果READ_COMMITTED_SNAPSHOT设置为ON,则数据库引擎使用行版本控制为每个语句显示在语句开头存在的数据的事务一致性快照。锁不用于保护数据免受其他事务的更新。

希望这有帮助。 拉吉

您是否考虑过创建DW的 DATABASE SNAPSHOT 关闭它的报告?

是。你的SQL可读性差得多。您将不可避免地错过一些NOLOCK提示,因为使用NOLOCK策略的SQL SELECT命令必须将它全部放在一起。

您可以通过设置隔离级别来获得相同的功能

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTING

最后你会获得10%的性能提升(对不起,我太懒了,太过于查找文章了,但它就在那里)

我认为10%的增益不值得降低可读性。

如果可以使整个数据库成为只读,那么这是一个更好的选择。无需修改所有代码即可获得读取未提交的性能。

ALTER DATABASE adventureworks SET read_only

NOLOCK执行'脏读'(猥亵READ UNCOMMITTED与NOLOCK做同样的事)。如果在您阅读时正在更新数据库,则存在您将获得不一致数据的危险。唯一的选择是接受锁定并因此阻塞,或者选择SQL 2005中提供的两个新隔离级别之一在这里讨论

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top