将 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 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
如何测试 MySql READ UNCOMMITTED 对 nolock 的使用
在 READ UNCOMMITTED 事务期间使用索引导致无法获取更新锁
MySQL - READ UNCOMMITTED 隔离级别是不是使用锁?
解决“set transaction isolation level read uncommitted;“命令无法修改MySQL数据库隔离级别的问题