-1

有一个查询需要超过一分钟才能运行
表有超过 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
4

2 回答 2

1

你有没有考虑用exists条款写它。像这样的东西

select distinct top 10001 a.[sID]
From [docSVsys] as a
where exists 
(
select *
From [docSVsys] as b
where b.[sID]<='1000'
and ( a.[sID] = b.[sID] OR a.[textHash] = b.[textHash])
)
于 2013-03-02T01:53:13.703 回答
0

答案在@NikolaMarkovinović 的评论中提供

select distinct isnull(docFam.sID, docSVsys.sID) as sID 
from  docSVsys 
left  join docSVsys as docFam 
  on  docSVsys.textHash = docFam.textHash 
where ...
于 2013-03-04T17:22:56.637 回答