在表上创建视图并从表中获取所有数据时对性能的影响



我想减少服务器上的锁定,因为我应用程序中的某些用户对数据库具有直接权限,并且他们在没有NOLOCK的情况下执行查询,这会在数据库中创建锁定。

为了减少这种情况,我想为数据库创建一个新架构,在此架构中,我将在数据库中存在的所有表上创建视图。在这个视图中,我将写为:

 select * from TABLE_NAME(nolock).

然后,我将仅向用户授予此架构的权限,这样它将减少锁定。

这种方法是一个好方法吗?它会在数据库中产生开销吗?

请指教。

从 BOL 上 NOLOCK ( READUNCOMMITED ( 提示:

指定允许脏读。没有共享锁颁发给 防止其他事务修改当前读取的数据 事务,而其他事务设置的独占锁不 阻止当前事务读取锁定的数据。允许 脏读可能会导致更高的并发性,但代价是读取 然后由其他事务回滚的数据修改。 这可能会为您的交易生成错误,向用户显示数据 从未提交,或导致用户查看记录两次(或不 根本(。

如果您可以接受,则可以考虑您的方法。当然,它会加快所有查询的性能。但是,我必须说这不是一个好主意,因为它可能会导致许多其他不可预测的错误 - 如果您使用NOLOCK读取的数据进行后续操作。

这是一篇很好的博客文章,介绍了使用NOLOCK的危险以及您可以实施的其他可能的解决方案,以避免使用它。

No.你的方法在很多层面上都有缺陷。至少你需要意识到两个问题:

  • NOLOCK 查询仍会创建锁:

READUNCOMMIT 和 NOLOCK 提示仅适用于数据锁。所有查询(包括具有 READUNCOMMIT 和 NOLOCK 提示的查询(都会在编译和执行期间获取 Sch-S(模式稳定性(锁。因此,当并发事务在表上持有 Sch-M(模式修改(锁时,查询将被阻止。

  • NOLOCK 查询产生不正确的结果

您应该考虑两种选择:

  • 最好创建数据库的备用只读副本,供这些用户运行其查询。您可以使用 AG 可读辅助数据库(豪华选项(、备用日志传送数据库、本地数据库快照或最后一个选项的复制。

  • 作为替代方法,在数据库中启用已提交读取快照,并让行版本控制消除争用。这可以说是一个更糟糕的选择,让用户查询备用数据,因为行版本控制会消耗资源,并且因为有权访问读写数据的用户可能会意外地最终修改数据甚至修改架构。

无论你选择什么,只要确保你摆脱了NOLOCK。它没有帮助,它不起作用。

最新更新