クエリの実行に 1 分以上かかる
テーブルには 200 万行を超える
[sID] が PK
[textHash] にインデックスが付けられており、null が許可され
ている 両方のインデックスの断片化は 1% 未満です
私がしたいのは [textHash] の一致を追加することです[ textHash
] は null になる可能性があるため、2 つの結合条件が必要です
他の条件が構築される方法のため、メイン選択での結合はオプションではありません。
次のメジャー リリースでは、UNION を使用できるようにクエリの作成方法が変更されます。
一般に、null になる可能性のあるプロパティに参加したい null
の場合は、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 のヒントを試してみました。
最初の 2 つはコンパイラによって拒否され、LOOP は遅くなり、ヒントはありませんでした。
私は試した
On ([docSVsys].[textHash] is null and [docSVsys].[sID] = [docFam].[sID])
Or [docSVsys].[textHash] = [docFam].[textHash]
しかも遅かった
同様のクエリは 2 秒で実行されますが
、この場合 [sParID] は null ではないため、必要な結合条件は 1 つだけです
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