5

誰かがこの動作またはそれを回避する方法を説明できますか?

このクエリを実行すると:

select * 
from TblA
left join freetexttable ( TblB, *, 'query' ) on TblA.ID = [Key]
inner join DifferentDbCatalog.dbo.TblC on TblA.ID = TblC.TblAID

非常に非常に遅くなります。

そのクエリを左結合の代わりに 2 つの内部結合を使用するように変更すると、非常に高速になります。内部結合の代わりに 2 つの左結合を使用するように変更すると、非常に高速になります。

freetexttable の代わりに SQL テーブル変数を使用すると、これと同じ動作を確認できます。

テーブル変数 (または freetexttable) とテーブルが別のデータベース カタログにあり、一方が内部結合にあり、もう一方が左結合にある場合は常に、パフォーマンスの問題が発生します。

なぜこれが遅いのか、またはそれを高速化する方法を知っている人はいますか?

4

4 に答える 4

8

一般的な経験則では、OUTER JOIN を使用すると結果セットの行数が増加し、 INNER JOIN を使用すると結果セットの行数が減少します。 もちろん、逆のシナリオもたくさんありますが、そうでない場合よりも、この方法でうまくいく可能性が高くなります。パフォーマンスのために必要なことは、結果セット (ワーキング セット) のサイズを可能な限り小さく保つことです。

両方の結合が最初のテーブルで一致するため、順序を変更しても結果の精度には影響しません。したがって、LEFT JOIN の前に INNER JOIN を実行することをお勧めします。

SELECT * 
FROM TblA
INNER JOIN DifferentDbCatalog.dbo.TblC on TblA.ID = TblC.TblAID
LEFT JOIN freetexttable ( TblB, *, 'query' ) on TblA.ID = [Key]

実際問題として、クエリ オプティマイザーは、結合に指定した順序に関係なく、より高速なオプションを使用するようにコンパイルできるほどスマートである必要があります。ただし、お粗末なクエリ オプティマイザがあり、クエリ操作が順番に行われているふりをすることをお勧めします。これは、将来のメンテナーがテーブルの性質に関する潜在的なエラーや仮定を見つけるのに役立ちます。

オプティマイザーは物事を書き直す必要があるため、これはおそらくあなたが見ている動作を完全に説明するのに十分ではありません. . ただし、これは学ぶべき良い原則です。

于 2008-09-06T00:20:56.577 に答える
4

通常行うべきことは、[Show Actual Execution Plan] オプションをオンにして、速度低下の原因を詳しく調べることです。(各結合の上にマウスを置くと、詳細が表示されます) テーブル スキャンではなく、インデックス シークを取得していることを確認する必要があります。

結合の 1 つを実行するために、SQL が 1 つのテーブルからすべてをメモリにプルすることを強制されていると思います。テーブルに参加する順序を逆にすることも役立つ場合があります。

于 2008-09-06T00:11:05.850 に答える
0

結合を実行するために使用するフィールドにインデックスを付けます。

経験則として、よく参照される外部キーまたは候補キーにインデックスを割り当てることをお勧めします。

于 2008-09-06T00:02:38.633 に答える
0

実行計画で繰り返し呼び出さfreetexttable(TblB, *, 'query')れる場合は、一時テーブルに配置すると役立つ場合があります。

于 2008-09-06T00:24:31.217 に答える