有一个查询需要超过一分钟才能运行
表有超过 200 万行
[sID] 是 PK
[textHash] 已编入索引并允许空值
两个索引的碎片都小于 1%
我想要添加 [textHash] 匹配到基本 where
由于 [textHash] 可以为 null 需要两个连接条件
由于在主选择上建立其他条件的方式,联盟不是一个选项。
在下一个主要版本中,将更改构建查询的方式以能够使用 UNION。
一般来说,我想加入一个可以为空的属性
如果它为空,则包含基于 PK 的行
Select top 10001 [docFam].[sID]
From [docSVsys] with (nolock)
LEFT OUTER JOIN [docSVsys] as [docFam] with (nolock)
On [docSVsys].[sID] = [docFam].[sID]
Or [docSVsys].[textHash] = [docFam].[textHash]
Where [docSVsys].[sID] <= '1000'
Group By [docFam].[sID]
Order By [docFam].[sID] Asc
如果有人会告诉我如何复制查询计划,我将包括它
我尝试了 HASH、MERGE 和 LOOP 提示。
前两个编译器拒绝并且 LOOP 较慢然后没有提示。
我试过
On ([docSVsys].[textHash] is null and [docSVsys].[sID] = [docFam].[sID])
Or [docSVsys].[textHash] = [docFam].[textHash]
而且速度较慢
类似的查询在 2 秒内运行
但在这种情况下 [sParID] 不为空,所以我只需要一个连接条件
Select top 10001 [docFam].[sID]
From [docSVsys] with (nolock)
LEFT OUTER JOIN [docSVsys] as [docFam] with (nolock)
On [docSVsys].[sParID] = [docFam].[sParID]
Where [docSVsys].[sID] <= '1000'
Group By [docFam].[sID]
Order By [docFam].[sID] Asc
对于返回少量行的查询 APPLY 有效。
下面的语法运行时间为 1 秒,而上面的语法运行时间为 1 分钟(返回 1,022 行)。
对于返回大量行的条件的两种形式的查询仍然存在问题,但我不认为这是 SQL 或语法问题 - 很多行需要更长的时间。
Select [docFam].[sID]
From [docSVsys] with (nolock)
OUTER APPLY -- cross apply
(
Select [docSVsysHashNull].[sID]
From [docSVsys] as [docSVsysHashNull]with (nolock)
where [docSVsysHashNull].[sID] = [docSVsys].[sID]
union
Select [docSVsysHashNotNull].[sID]
From [docSVsys] as [docSVsysHashNotNull]with (nolock)
where [docSVsysHashNotNull].[sID] != [docSVsys].[sID]
and [docSVsysHashNotNull].[textHash] = [docSVsys].[textHash]
) as docFam
Where [docSVsys].[sID] <= '1000'
Group By [docFam].[sID]
Order By [docFam].[sID] Asc