Dav*_*het 1 sql-server sql-server-2008
我有一个MyTable表和一个字段MyField,它是varbinary(max).我有以下查询:
SELECT COUNT(*) FROM MyTable WHERE MyField IS NOT NULL
Run Code Online (Sandbox Code Playgroud)
SELECT子句可以有任何东西,没关系.由于Where子句中的varbinary MyField,执行永远不会结束.
我甚至试过这个:
SELECT Size
FROM
(
SELECT ISNULL(DATALENGTH(MyField), 0) AS Size FROM MyTable
) AS A
WHERE A.Size > 0
Run Code Online (Sandbox Code Playgroud)
内部查询工作正常,没有Where子句的整个查询工作正常,但使用Where子句它被卡住了.有人可以向我解释一下吗?
谢谢.
不要认为或假设它不可能阻塞,只是因为不同的查询立即返回.使用不同的where子句,不同的计划,以及可能不同的锁定升级,您当然可能会遇到一个查询被阻止而另一个查询被阻止的情况,即使是针对同一个表.
如果您对"卡住"的定义是我认为的那样,那么查询显然会被阻止.现在你只需要由谁来确定.
在一个查询窗口中,执行以下操作:
SELECT @@SPID;
Run Code Online (Sandbox Code Playgroud)
记下这个号码.现在在同一个查询窗口中,运行"卡住"的查询(换句话说,不要在一个窗口中选择spid并期望它与已在另一个窗口中运行的查询有关).
然后,在不同的查询窗口中,执行以下操作:
SELECT blocking_session_id, status, command, wait_type, last_wait_type
FROM sys.dm_exec_requests
WHERE session_id = <spid from above>;
Run Code Online (Sandbox Code Playgroud)
这是一个我怀疑可能有帮助的可视化(注意我的"卡住"查询与您的不同):
如果在第一列中获得非零数字,则在该不同的查询窗口中,执行以下操作:
DBCC INPUTBUFFER(<that blocking session id>);
Run Code Online (Sandbox Code Playgroud)
如果你没有被封锁,我很想知道其他专栏的内容.
顺便说WHERE一句,更改子句以使用稍微不同的谓词来标识相同的行并不会神奇地消除阻塞.此外,这样做没有任何实际好处:
SELECT Size
FROM
(
SELECT ISNULL(DATALENGTH(MyField), 0) AS Size FROM MyTable
) AS A
WHERE A.Size > 0
Run Code Online (Sandbox Code Playgroud)
当你可以这样做:
SELECT ISNULL(DATALENGTH(MyField), 0) AS Size
FROM dbo.MyTable -- always use schema prefix
WHERE DATALENGTH(MyField) > 0; -- always use semi-colon
Run Code Online (Sandbox Code Playgroud)
DATALENGTH如果你担心的话,SQL Server足够智能,不能计算两次.
只是为了好玩和咯咯笑,我决定把这个扔给你.我在这里把一些事情视为理所当然,但你可以看看必须等待的任务.查找以等待开头的等待类型,LCK_因为这些将是您的阻止任务.请注意,在繁忙的服务器上,环形缓冲区可能会在一段时间后翻转.另请注意,这是为了补充@ AaronBertran的优秀答案,绝不意味着取代它.他的内容更全面,是在问题发生时识别问题的正确方法.
SELECT
td.r.value('@name','sysname') event_name,
td.r.value('@timestamp','datetime2(0)') event_timestamp,
td.r.value('(data[@name="wait_type"]/text)[1]','sysname') wait_type,
td.r.value('(data[@name="duration"]/value)[1]','bigint') wait_duration,
td.r.value('(action[@name="sql_text"]/value)[1]','nvarchar(max)') sql_text,
td.r.query('.') event_data
FROM (
SELECT
CAST(target_data AS XML) target_data
FROM sys.dm_xe_sessions s
JOIN sys.dm_xe_session_targets t
ON s.address = t.event_session_address
WHERE s.name = N'system_health'
and target_name = 'ring_buffer'
) base
CROSS APPLY target_data.nodes('/RingBufferTarget/*') td(r)
where td.r.value('@name','sysname') = 'wait_info';
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
655 次 |
| 最近记录: |