0

次のようなクエリがあります。

select X.id_x, A.id_a, B.id_b
from X
left join A on 'A|' + A.id_a = X.id_aOrB
left join B on 'B|' + B.id_b = X.id_aOrB

X は A または B にリンクされ、id は結合ステートメントで計算されます。

  • X: 8 000 行
  • A: 36,000 行
  • B: 3,000 行

このクエリは非常に遅く、10 秒程度です。にインデックスがありませんX.id_aOrb

'A|' + id次に、トリガーによって更新される 2 つの「結合」テーブルを使用すると、 andを連結する必要はありません'B|'+id。結果は 1 秒未満で取得されます。わかった。

私の質問: なぜこの連結はとても遅いのですか? データが多すぎる場合、SQL Server は '+' であまり効率的ではありませんか?

4

3 に答える 3

1
FROM X
LEFT JOIN A on 'A|' + A.id_a = X.id_aOrB

sargable ではありません (SQL Server はインデックスを使用できません)。

Aネストされたループ結合を使用する場合は、にある行と同じ回数スキャンする必要がありますX。述語Aを評価するためにインデックス シークを実行することはできません。'A|' + A.id_a = X.id_aOrB

マージ結合を使用する場合、インデックスからの順序を使用できるのではなく、データのコピーを取得して最初に並べ替える必要があります。

もちろん、参加も同様ですB

于 2013-01-31T16:10:35.320 に答える
0

次のクエリは高速ですか?

With t as
(
  select id_x,SUBSTRING(X.id_aOrB,3,1000) as id_a,null as id_b
  from x
  where X.id_aOrB like 'A|%'
  union all
  select id_x,NULL as id_a,SUBSTRING(X.id_aOrB,3,1000) as id_b
  from x
  where X.id_aOrB like 'B|%'
)
select t.id_x, A.id_a, B.id_b
from t
left join A on A.id_a = t.id_a
left join B on B.id_b = t.id_b
于 2013-01-31T15:53:26.583 に答える
0

実行計画を見て、最も多くの時間を費やしている場所を確認します。SQL はテーブル スキャンを実行していますか? 彼らは非常に遅いです。X.id_aOrB にインデックスがない場合は、これを最適化することをお勧めします。実行計画を解釈する方法に関するいくつかの記事はこちら.

このクエリを頻繁に実行する場合は、そこからビューを作成し、インデックスを作成して具体化することができます (ただし、メンテナンスにはコストがかかります...)

于 2013-01-31T15:51:03.963 に答える