有没有理由为查询添加一个nolock会导致它增加执行时间?
UPDATE TargetTable
SET col1 = c1.RowCnt,
col2 = c2.RowCnt
from TargetTable tt
join
(
select col3, RowCnt = NULLIF(COUNT(*),0) from Table2 (nolock)
group by col3
) c1 on c1.col3 = tt.ID
join
(
select col4, RowCnt = NULLIF(COUNT(*),0) from Table2 (nolock)
group by col4
) c2 on c2.col4 = tt.ID
WHERE timestamp BETWEEN @FromDate AND @ToDate
AND (tt.Client_ID = @Client_ID)
答案 0 :(得分:2)
NOLOCK提示允许Allocation Order Scans。因此,他们可能会创建一个完全不同的执行计划,一个预计会更快,但事实证明它更慢(例如由于陈旧的统计数据而导致错误的基数估计)。与任何性能问题一样,使用调查方法找出问题的原因。 Waits and Queues是一种非常出色的方法。
答案 1 :(得分:1)
这张表是否有很多写活动?在两种情况下,您确定正确的行会受到影响吗?您是否尝试过使用SET TRANSACTION ISOLATION LEVEL而不是在查询中添加个别提示?
UPDATE tt SET
col1 = NULLIF(c1.RowCnt, 0),
col2 = NULLIF(c2.RowCnt, 0)
FROM dbo.TargetTable AS tt
INNER JOIN
(
SELECT col3, RowCnt = COUNT(*)
FROM dbo.Table2 WITH (NOLOCK)
GROUP BY col3
) AS c1 ON c1.col3 = tt.ID
INNER JOIN
(
SELECT col4, RowCnt = COUNT(*)
FROM dbo.Table2 WITH (NOLOCK)
GROUP BY col4
) AS c2 ON c2.col4 = tt.ID
WHERE tt.[timestamp] BETWEEN @FromDate AND @ToDate
AND tt.Client_ID = @Client_ID;
-- with SQL Server's UPDATE FROM syntax, you should reference the alias in the UPDATE
-- use WITH (NOLOCK), as your current syntax could become an alias in later versions
-- get in the habit of using dbo. prefix and statement terminators
-- are you sure you don't want left joins?
答案 2 :(得分:0)
不是我听过的。我会看一下:
- 更改是表格中的数据,用于更改查询的总体成本
- 锁定正在更新的表的其他服务器活动
- 降低CPU可用性的其他服务器活动
- 使用硬盘的后台操作系统任务