数据库视图性能问题

Posted

技术标签:

【中文标题】数据库视图性能问题【英文标题】:Database view performance issue 【发布时间】:2009-06-11 08:03:53 【问题描述】:

我正在使用 SQL Server 2008,并且我有两个具有相同架构的表,并且我创建了一个视图,该视图将两个表的内容结合起来,以便为外部访问提供一个“表”视图。

其中一个表是只读的,另一个表包含批量插入/删除操作(在另一张表上,我将每隔一段时间使用批量插入插入每千行并运行另一个 SQL 作业以删除几百万行每天)。

我的问题是,如果另一个表在批量插入/删除操作,物理表是否会被锁定,这样外部用户对两个表的联合视图的访问也会被阻止? (我在想这个场景是不是加锁,行锁最终锁住了表,最终锁住了视图的访问?)

【问题讨论】:

【参考方案1】:

如果另一个表在进行批量插入/删除操作,是否会锁定物理表,从而阻止外部用户访问两个表的联合视图?

是的,需要注意的是,如果优化器可以找到一种方法来执行不涉及访问批量插入表的查询,则不会阻止访问。

如果您希望优化批量加载时间,请确保您已阅读 this blog post。

编辑

您遇到的实际问题是什么?你真的需要在任何地方都使用这个视图吗(例如,是否有地方只需要一个表中的数据,通过视图查询它?)

如果您希望查看始终“在线”,请考虑快照隔离,或者如果您将完整集加载​​到批量表中(例如,每天替换全部内容),您可以将数据加载到单独的表和 sp_rename 中的表(在事务中)

【讨论】:

对不起,我的措辞令人困惑。我的意思是我有两个操作另一个表(1)批量插入(2)每天删除数百万行(不是批量删除和批量插入)。我认为即使对于(1)批量插入查询优化器可以找到优化方法,对于(2)删除操作,表将被锁定(发生锁定升级?)并且对视图的查询将被锁定? @sambo99,还有一个问题,我仔细阅读了你提到的文档,我很困惑堆表和带聚集索引的表有什么区别? 是的,我一直需要在线视图。 “快照隔离”是指读取脏数据的nolock解决方案吗? "或者如果您将完整的集合加载到批量表中(例如,每天替换全部内容),您可以将数据加载到单独的表中并在(在事务中)sp_rename 表" -- 不可行,因为我将每 20 分钟对新的数千行进行批量插入。 我认为您需要发布一些关于 nolock 和快照隔离的单独问题。【参考方案2】:

很可能是的。这取决于锁升级

解决方法(不是所有选项):

使用 WITH (NOLOCK) 表提示忽略并且不设置任何锁。如果在视图上使用它也适用于两个表

如果您不介意跳过 BCP 表中的锁定行,请使用 WITH (READPAST)

更改 BCP 表的锁定粒度。使用sp_tableoption 并设置“批量加载时的表锁定”=false。

编辑:现在我已经喝过咖啡了……

如果您需要在加载/删除操作期间查询批量表并且获得准确的结果并且不遭受性能损失,我建议您需要考虑 SNAPSHOT 隔离 p>

编辑2:SNAPSHOT isolation

【讨论】:

出于对所有美好事物的热爱,请不要建议使用 (nolock) 作为治疗所有锁定疾病的方法。 @gbn,1. 我对 nolock 选项感到困惑。 nolock 选项会在并发操作(查询/插入/删除)期间对数据完整性造成任何风险吗?感谢您是否可以向我推荐一些有关 nolock 工作原理以及我们应该在什么情况下使用 nolock 选项的读物? 2.我认为使用“READPAST”不会对查询结果做出准确的响应?例如,在 BCP 操作中,查询可能有命中行,但是如果我们使用 READPAST 操作绕过,客户端将什么也得不到。有没有cmets? NOLOCK 不会影响数据的加载。它不使用共享锁并且忽略其他锁但是,您有读取脏数据、正在删除的数据、必须回滚的数据等的风险。READPAST 在加载期间会给出不准确的结果 谢谢@gbn,1。我很困惑。您的意思是在查询客户端上使用 nolock,而不是在插入/删除过程中使用 nolock? 2. READPAST 是否会读取脏数据(例如尚未提交的数据)? 1.仅用于读取数据 2. 不,它会忽略任何正在更改的内容(有锁)

以上是关于数据库视图性能问题的主要内容,如果未能解决你的问题,请参考以下文章

动态性能视图

sqlite3 视图影响性能?

表与视图的性能

创建数据库视图与创建 Hibernate 映射 - 性能 [关闭]

使用视图提高查询性能

Oracle实验三—数据字典和性能视图的使用