带有varbinary的where子句不起作用

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子句它被卡住了.有人可以向我解释一下吗?

谢谢.

Aar*_*and 6

不要认为或假设它不可能阻塞,只是因为不同的查询立即返回.使用不同的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)

这是一个我怀疑可能有帮助的可视化(注意我的"卡住"查询与您的不同):

点击embiggen

如果在第一列中获得非零数字,则在该不同的查询窗口中,执行以下操作:

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足够智能,不能计算两次.

  • @DavidShochet并不意味着你没有更大的问题!我不要重复**不要错误地将一些神秘的东西误解为解决方案. (4认同)
  • 开始购买魔术公司的股票?最起码,现在你有下一次追查问题的方法(你只需要正确地按照指示,并确保该查询实际上仍然是"卡住"当你尝试检查什么它卡住). (2认同)
  • @DavidShochet我建议使用我链接的存储过程来获取并了解在减速或延迟期间服务器发生了什么.现在所有的证据都指向其他东西阻止你的查询,这意味着它可能会再次发生.使用SP_who3以查看在这些时间内服务器上发生的情况. (2认同)

swa*_*eck 5

只是为了好玩和咯咯笑,我决定把这个扔给你.我在这里把一些事情视为理所当然,但你可以看看必须等待的任务.查找以等待开头的等待类型,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)