将 READ UNCOMMITTED 与 UNION ALL 一起使用

Posted

技术标签:

【中文标题】将 READ UNCOMMITTED 与 UNION ALL 一起使用【英文标题】:Using READ UNCOMMITTED with UNION ALL 【发布时间】:2014-12-31 16:08:59 【问题描述】:

我有一个正在开发中的存储过程,其中包含多个 UNION ALL 语句。这是历史数据,我被指示使用SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED。撇开关于这是否是正确方法的讨论,我想知道我是否需要在存储过程的顶部只指定一次 ISOLATION LEVEL,或者是否需要在每个 UNION ALL 之后指定它,因为它们'是不同的查询?

例子:

Alter procedure dbo.ExampleProcedure as
declare @StartDate datetime
declare @EndDate datetime
insert into myDB.DBO.InboundCalls

select I.Date, I.System, Count(*) as calls
from
(select Date, System, CallID from System1CallData C
Left Join someothertables as S on C.CallID = S.CallID
where (C.date >= @StartDate and C.date < @EndDate)) as I
Group by I.Date, I.System

Union ALL

select I.Date, I.System, Count(*) as calls
from
(select Date, System, CallID from System2CallData C
Left Join someothertables as S on C.CallID = S.CallID
where (C.date >= @StartDate and C.date < @EndDate)) as I
group by I.Date, I.System

Union ALL

select I.Date, I.System, Count(*) as calls
from
(select Date, System, CallID from System3CallData C
Left Join someothertables as S on C.CallID = S.CallID
where (C.date >= @StartDate and C.date < @EndDate)) as I
Group by I.Date, I.System
Order by I.Date asc, I.System asc, calls asc

那么我应该将SET TRANSACTION ISOLATION LEVEL 放在Alter Procedure dbo.ExampleProcedure as 之后,还是在第一个SELECT 之前,或者在每个嵌套的SELECT 之前?提前感谢您的任何指导!

【问题讨论】:

insert into... 之前,而不是在select... 之前。 【参考方案1】:

我想知道是否只需要在存储过程的顶部指定一次此 ISOLATION LEVEL 。 . .

在程序的顶部只有一次,除非您当然要在程序切换隔离级别。 SP 退出时isolation level reverts 到上一级。

如果您在存储过程中发出 SET TRANSACTION ISOLATION LEVEL 或 触发器,当对象返回控制时,隔离级别被重置 到调用对象时的有效级别。例如,如果 您在批处理中设置 REPEATABLE READ,然后批处理调用存储的 将隔离级别设置为 SERIALIZABLE 的过程,即隔离 存储过程时级别设置恢复为 REPEATABLE READ 将控制权返回给批处理。

使用“读取未提交”隔离级别可能对历史数据没有风险。我假设指示您使用该隔离级别的人知道风险并确定它是安全的。

历史数据通常要么根本不改变,要么以已知的时间间隔改变。 (比如说,每季度一次。或者每天凌晨 1:00。)我预计相对较少的人拥有这些表的插入权限,几乎没有人拥有更新和删除权限。

您还可以测试在单个事务中运行三个单独的插入语句,而不是插入三个选择语句的联合。 ORDER BY 子句在生产中可能是个坏主意。

【讨论】:

@GunslingerFyre:不客气。我添加了一些您可能会觉得有用的信息。您似乎对 SO 不太活跃,但您应该知道您可以同时支持 接受答案。 @Mike,你应该知道voting up requires 15 rep,如果你对他们的问题投了赞成票,OP 就会知道。 :-) ...只是说,它是双向的。如果这个问题足够好回答,它可能也足以让你投票。 “在历史数据上可能没有风险”,但也可能没有太多好处。它不应该被并发活动阻塞,如果页面最近没有更新,SQL Server 已经可以在读取提交时跳过获取行锁。 @MikeSherrill'CatRecall',我试图支持你的答案,但正如 Aaron 所说,我没有足够的代表 :) 实际上,现在我确实有足够的代表,所以我赞成。跨度>

以上是关于将 READ UNCOMMITTED 与 UNION ALL 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

Read Uncommitted

为啥使用 READ UNCOMMITTED 隔离级别?

如何测试 MySql READ UNCOMMITTED 对 nolock 的使用

在 READ UNCOMMITTED 事务期间使用索引导致无法获取更新锁

MySQL - READ UNCOMMITTED 隔离级别是不是使用锁?

解决“set transaction isolation level read uncommitted;“命令无法修改MySQL数据库隔离级别的问题