在以下查询中,我将WITH(NOLOCK)
放在哪里?
SELECT *
FROM (SELECT *
FROM (SELECT *
FROM (SELECT *
FROM (SELECT *
FROM dbo.VBsplit(@mnemonicList, ',')) a) b
JOIN dct
ON dct.concept = b.concept
WHERE b.geo = dct.geo) c
JOIN dct_rel z
ON c.db_int = z.db_int) d
JOIN rel_d y
ON y.rel_id = d.rel_id
WHERE y.update_status = 0
GROUP BY y.rel_id,
d.concept,
d.geo_rfa
答案 0 :(得分:10)
您不应将NOLOCK
放在该查询中的任何位置。如果你试图阻止读者阻止作者,那么更好的选择是READ COMMITTED SNAPSHOT
。当然,您应该阅读此内容,就像您应该在将NOLOCK
盲目地投入查询之前阅读VBSplit()
一样:
NOLOCK
SQL Server hint bad practice? NOLOCK
always bad? 此外,由于您使用的是SQL Server 2008,因此您可能应该使用表值参数替换CREATE TYPE dbo.Strings AS TABLE(Word NVARCHAR(900) PRIMARY KEY);
函数 - 这将比分割字符串更有效,即使函数已烘焙在CLR中暗示。
首先,创建一个可以容纳相应字符串的表类型。我将假设该列表保证是唯一的,并且没有单独的助记词可以是> 900个字符。
CREATE PROCEDURE dbo.Whatever
@Strings dbo.Strings READONLY
AS
BEGIN
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL --<choose wisely>;
SELECT -- please list your columns here instead of *
FROM @Strings AS s
INNER JOIN dbo.dct -- please always use proper schema prefix
ON dct.concept = s.Word
...
END
GO
现在,您可以创建一个过程,该过程采用此类型的参数,并在一个位置设置您选择的隔离级别:
{{1}}
现在你可以简单地从你的应用程序中传递一个集合(例如DataTable),无论是C#还是其他什么,而且根本不需要组装或解构一个混乱的逗号分隔列表。
答案 1 :(得分:3)
因为问题确实存在,“我应该把NOLOCK放在哪里”。我不打算讨论使用OR重新格式化查询与更好的连接。我将回答这个问题。
我绝不打算说这是更好的方式,或者说其他答案都不好。另一个答案解决了实际问题。我只是打算显示确切地放置锁定提示的位置,问题是
SELECT *
FROM (SELECT *
FROM (SELECT *
FROM (SELECT *
FROM (SELECT *
FROM dbo.VBsplit(@mnemonicList, ',')) a) b
JOIN dct WITH (NOLOCK) -- <---
ON dct.concept = b.concept
WHERE b.geo = dct.geo) c
JOIN dct_rel z WITH (NOLOCK) -- <---
ON c.db_int = z.db_int) d
JOIN rel_d y WITH (NOLOCK) -- <---
ON y.rel_id = d.rel_id
WHERE y.update_status = 0
GROUP BY y.rel_id,
d.concept,
d.geo_rfa
答案 2 :(得分:2)
像这样,使用最整洁的方法。
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM (SELECT * FROM
(SELECT * FROM (SELECT * FROM
(SELECT * FROM dbo.VBsplit(@mnemonicList,',')) a ) b
JOIN dct ON dct.concept = b.concept WHERE b.geo = dct_variable.geo_rfa) c
JOIN dct_rel z ON c.db_int = z.db_int) d
JOIN rel_d y ON y.rel_id = d.rel_id
WHERE y.update_status = 0
GROUP BY y.rel_id,d.concept,d.geo_rfa
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
但是,除非您在活动数据库上将其用于报告目的,否则启用脏读可能不是最好的方法。
编辑为(NOLOCK)本身不会被弃用,除非此处描述:http://technet.microsoft.com/en-us/library/ms143729.aspx。