[FIX] 外部結合およびフィルタ選択条件を結果の大きな結合および外部結合の前に実行する

文書翻訳 文書翻訳
文書番号: 318530 - 対象製品
すべて展開する | すべて折りたたむ

現象

外部結合の内部テーブル (左外部結合の右テーブル、右外部結合の左テーブルなど) の WHERE 句にフィルタ選択条件を使用する外部結合を少なくとも 1 つ含むクエリを実行すると、SQL Server は、先に外部結合を実行してからフィルタ選択条件を適用するという手順ではなく、最初に結果の大きな結合を実行することがあります。外部結合のフィルタ選択条件が、より結果の小さなクエリ条件であった場合、プランでこの条件を先に処理しないと、以下の現象が発生することがあります。
  • 中間結合サイズが大きくなる。
  • SQL Server プロセスのリソース使用率が高くなる。
  • クエリに対する応答時間が長くなる。

解決方法

この問題を解決するには、Microsoft SQL Server 2000 の最新の Service Pack を入手します。関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
290211 最新の SQL Server 2000 Service Pack の入手方法
: 次の修正プログラムは Microsoft SQL Server 2000 Service Pack 3 がリリースされる前に作成されました。

修正プログラム (英語版) の属性は次のとおりです。ただし、これより新しい修正プログラムがリリースされている可能性もあります。
   バージョン       ファイル名
   -----------------------------

   8.00.0584     Sqlservr.exe
				
: ファイルの依存関係のため、上記のファイルを含む最新の修正プログラムや機能には、追加ファイルも含まれる可能性があります。


状況

マイクロソフトでは、この問題をこの資料の冒頭に記載したマイクロソフト製品の問題として認識しています。
この問題は、Microsoft SQL Server 2000 Service Pack 3 で最初に修正されました。

詳細

以下の例では、上記の結合について説明するために、pubs データベースを使用しています。
set ansi_nulls off
go

use pubs
go

create procedure dbo.ansi_nulls_param @P1 varchar(11) as
select t.title_id, a.au_id, ta.title_id, s.stor_id from titles t 
   left outer join titleauthor ta on ta.title_id = t.title_id
   inner join authors a on a.au_id = t.title_id
   inner join sales s on s.title_id = t.title_id
where ta.title_id = @P1
go

exec dbo.ansi_nulls_param '123-45-6789'
go

drop proc dbo.ansi_nulls_param
go

--Slower Query Plan:
       |--Filter(WHERE:([ta].[title_id]=[@P1]))
            |--Nested Loops(Left Outer Join, OUTER REFERENCES:([t].[title_id]))
                 |--Nested Loops(Inner Join, OUTER REFERENCES:([s].[title_id]))
                 |    |--Nested Loops(Inner Join, OUTER REFERENCES:([s].[title_id]))
                 |    |    |--Index Scan(OBJECT:([pubs].[dbo].[sales].[titleidind] AS [s]))
                 |    |    |--Clustered Index Seek(OBJECT:([pubs].[dbo].[authors].[UPKCL_auidind] AS [a]), SEEK:([a].[au_id]=[s].[title_id]) ORDERED FORWARD)
                 |    |--Clustered Index Seek(OBJECT:([pubs].[dbo].[titles].[UPKCL_titleidind] AS [t]), SEEK:([t].[title_id]=[s].[title_id]) ORDERED FORWARD)
                 |--Index Seek(OBJECT:([pubs].[dbo].[titleauthor].[titleidind] AS [ta]), SEEK:([ta].[title_id]=[t].[title_id]) ORDERED FORWARD)

--Faster Query Plan:
       |--Nested Loops(Inner Join, OUTER REFERENCES:([a].[au_id]))
            |--Nested Loops(Inner Join, OUTER REFERENCES:([t].[title_id]))
            |    |--Filter(WHERE:([ta].[title_id]=[@P1]))
            |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([t].[title_id]))
            |    |         |--Index Scan(OBJECT:([pubs].[dbo].[titles].[titleind] AS [t]))
            |    |         |--Index Seek(OBJECT:([pubs].[dbo].[titleauthor].[titleidind] AS [ta]), SEEK:([ta].[title_id]=[t].[title_id]) ORDERED FORWARD)
            |    |--Clustered Index Seek(OBJECT:([pubs].[dbo].[authors].[UPKCL_auidind] AS [a]), SEEK:([a].[au_id]=[t].[title_id]) ORDERED FORWARD)
            |--Index Seek(OBJECT:([pubs].[dbo].[sales].[titleidind] AS [s]), SEEK:([s].[title_id]=[a].[au_id]) ORDERED FORWARD)
				
titleauthor テーブルは左外部結合の右テーブルであり、titleauthor テーブルの WHERE 句の条件は外部結合の後に適用されます。最初の出力では、低速なクエリ プランが表示されています。このクエリ プランでは、最初にすべての内部結合が実行され、最後に外部結合とフィルタ選択が実行されます。フィルタ選択がこのクエリで最も結果が小さくなる条件であっても、この順序は変わりません。2 番目のクエリ プランは高速のプランを示すために作成したものです。高速なプランでは外部結合とフィルタ選択が実行された後、内部結合が実行されます。

この例の場合、修正プログラムの適用後もオプティマイザは最初のプランを選択します。これは、テーブルが非常に小さいので最初のプランの見積もりコストが低く、その後の選択肢を探すよりも最初のプランを実行する方が効率が良いと判断されるからです。テーブル内のデータが増えると最初のプランのコストが高くなり、オプティマイザは 2 番目のプランを選択するようになります。

プロパティ

文書番号: 318530 - 最終更新日: 2006年6月22日 - リビジョン: 4.2
この資料は以下の製品について記述したものです。
  • Microsoft SQL Server 2000 Standard Edition
キーワード:?
kbhotfixserver kbqfe kbsqlserv2000sp3fix kbbug kbfix kbsqlserv2000presp3fix KB318530
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com