テーブル ヒント (Transact-SQL)
テーブル ヒントでは、ロック手法、1 つ以上のインデックス、クエリ処理操作 (テーブル スキャンやインデックスのシークなど)、またはその他のオプションを指定することによって、データ操作言語 (DML) ステートメントが存続する間だけ、クエリ オプティマイザの既定の動作を無効にします。
注意 |
---|
通常、SQL Server クエリ オプティマイザでは、クエリにとって最適な実行プランが選択されるため、ヒントは、経験を積んだ開発者やデータベース管理者が最後の手段としてのみ使用することをお勧めします。 |
適用対象
構文
WITH ( <table_hint> [ [ , ]...n ] )
<table_hint> ::=
[ NOEXPAND ] {
INDEX ( index_value [ ,...n ] ) | INDEX = ( index_value )
| FASTFIRSTROW
| FORCESEEK
| HOLDLOCK
| NOLOCK
| NOWAIT
| PAGLOCK
| READCOMMITTED
| READCOMMITTEDLOCK
| READPAST
| READUNCOMMITTED
| REPEATABLEREAD
| ROWLOCK
| SERIALIZABLE
| TABLOCK
| TABLOCKX
| UPDLOCK
| XLOCK
}
<table_hint_limited> ::=
{
KEEPIDENTITY
| KEEPDEFAULTS
| FASTFIRSTROW
| HOLDLOCK
| IGNORE_CONSTRAINTS
| IGNORE_TRIGGERS
| NOWAIT
| PAGLOCK
| READCOMMITTED
| READCOMMITTEDLOCK
| READPAST
| REPEATABLEREAD
| ROWLOCK
| SERIALIZABLE
| TABLOCK
| TABLOCKX
| UPDLOCK
| XLOCK
}
引数
WITH ( <table_hint> ) [ [ , ]...n ]
いくつかの例外を除き、テーブル ヒントは、FROM 句で WITH キーワードを使用して指定した場合にのみサポートされます。また、テーブル ヒントはかっこを使用して指定する必要があります。重要 WITH キーワードを省略することは推奨されていません。この機能は、将来のバージョンの Microsoft SQL Server では削除される予定です。 新しい開発作業では、この機能の使用を避け、現在この機能を使用しているアプリケーションは修正するようにしてください。
WITH キーワードの有無にかかわらず使用できるテーブル ヒントは、NOLOCK、READUNCOMMITTED、UPDLOCK、REPEATABLEREAD、SERIALIZABLE、READCOMMITTED、FASTFIRSTROW、TABLOCK、TABLOCKX、PAGLOCK、ROWLOCK、NOWAIT、READPAST、XLOCK、および NOEXPAND です。これらのテーブル ヒントを WITH キーワードを使用せずに指定するときは、単独で指定してください。次に例を示します。
FROM t (TABLOCK)
ヒントを他のオプションと一緒に指定する場合は、次のように WITH キーワードを使用して指定する必要があります。
FROM t WITH (TABLOCK, INDEX(myindex))
複数のテーブル ヒント間にはコンマを使用することをお勧めします。
重要 ヒントの分割にコンマの代わりにスペースを用いる方法は推奨されていません。この機能は、Microsoft SQL Server の将来のバージョンで削除されます。 新規の開発作業ではこの機能を使用しないようにし、現在この機能を使用しているアプリケーションはできるだけ早く修正してください。
この制限は、互換性レベル 90 以上のデータベースに対するクエリでヒントを使用する場合に適用されます。
NOEXPAND
クエリ オプティマイザがクエリを処理する場合に、インデックス付きビューが展開されず、基になるテーブルがアクセスされないことを指定します。クエリ オプティマイザは、ビューをクラスタ化インデックスを持つテーブルのように取り扱います。NOEXPAND はインデックス付きビューにのみ適用できます。詳細については、「解説」を参照してください。INDEX ( index_value [ ,... n ] ) | INDEX = ( index_value )
INDEX() 構文では、ステートメントを処理するときにクエリ オプティマイザが使用する 1 つ以上のインデックスの名前または ID を指定します。一方、INDEX = 構文では、単一のインデックス値を指定します。各テーブルに対して指定できるのは 1 つのインデックス ヒントだけです。クラスタ化インデックスがある場合、INDEX(0) はクラスタ化インデックスのスキャンを実行し、INDEX(1) はクラスタ化インデックスのスキャンまたはシークを実行します。クラスタ化インデックスがない場合、INDEX(0) はテーブル スキャンを実行し、INDEX(1) はエラーと見なされます。
1 つのヒント リストの中で複数のインデックスが使用されている場合、重複するものは無視され、リスト内の残りのインデックスを使用してテーブルの行が取得されます。インデックス ヒント内のインデックスの順番は重要です。複数のインデックス ヒントはインデックスの AND 処理も設定し、クエリ オプティマイザはアクセスされる各インデックスに可能な限り多くの条件を適用します。ヒント インデックスの集合に、クエリで参照される列のすべてが含まれているわけではない場合、SQL Server データベース エンジンがすべてのインデックス列を取得した後で、残りの列を取得するフェッチが実行されます。
注意 複数のインデックスを参照するインデックス ヒントが、スター結合のファクト テーブルで使用されている場合、オプティマイザはそのインデックス ヒントを無視し、警告メッセージを返します。また、インデックス論理和は、インデックス ヒントが指定されたテーブルでは許可されません。
テーブル ヒント内のインデックスの最大個数は、非クラスタ化インデックスが 250 個です。
KEEPIDENTITY
INSERT ステートメントで、BULK オプションが OPENROWSET と一緒に使用されているときにのみ適用できます。インポートしたデータ ファイルの ID 値 (複数可) を ID 列に使用することを指定します。KEEPIDENTITY を指定しない場合、この列の ID 値は確認されるのみでインポートされません。クエリ オプティマイザは、テーブルの作成時に指定された seed および increment の値を基に一意な値を自動的に割り当てます。
重要 テーブルやビューの ID 列の値がデータ ファイルに含まれておらず、ID 列がテーブルの最終列でもない場合は、その ID 列をスキップする必要があります。詳細については、「フォーマット ファイルを使用したデータ フィールドのスキップ」を参照してください。ID 列のスキップに成功すると、クエリ オプティマイザは、その ID 列の一意な値を、インポートされたテーブル行に自動的に割り当てます。
このヒントを INSERT ...SELECT * FROM OPENROWSET(BULK...) ステートメントで使用する例については、「データの一括インポート時の ID 値の保持」を参照してください。
テーブルの ID 値の確認については、「DBCC CHECKIDENT (Transact-SQL)」を参照してください。
KEEPDEFAULTS
INSERT ステートメントで、BULK オプションが OPENROWSET と一緒に使用されているときにのみ適用できます。データ レコードにテーブルの列値が含まれていない場合に、NULL の代わりにテーブル列の既定値を挿入することを指定します。
このヒントを INSERT ...SELECT * FROM OPENROWSET(BULK...) ステートメントで使用する例については、「一括インポート中の NULL の保持または既定値の使用」を参照してください。
FASTFIRSTROW
OPTION (FAST 1) に相当します。詳細については、「クエリ ヒント (Transact-SQL)」を参照してください。重要 この機能は、Microsoft SQL Server の次のバージョンで削除されます。 新規の開発作業ではこの機能を使用しないようにし、現在この機能を使用しているアプリケーションはできるだけ早く修正してください。
FORCESEEK
クエリ オプティマイザに対し、クエリで参照されているテーブルやビューのデータへのアクセス パスとしてインデックスのシーク操作のみを使用することを指定します。FORCESEEK は、クラスタ化インデックスのシーク操作と非クラスタ化インデックスのシーク操作の両方に適用されます。SELECT ステートメントの FROM 句や、UPDATE ステートメント、MERGE ステートメント、または DELETE ステートメントの FROM <table_source> 句の任意のテーブルやビューに対して指定できます。
FORCESEEK を指定する際には、INDEX ヒントを使用してもしなくてもかまいません。インデックス ヒントと組み合わせた場合、指定したインデックス経由のシーク アクセス パスのみがクエリ オプティマイザによって検討されます。FORCESEEK が原因でプランが見つからない場合、エラー 8622 が返されます。詳細については、「FORCESEEK テーブル ヒントの使用」を参照してください。
HOLDLOCK
SERIALIZABLE に相当します。詳細については、後の「SERIALIZABLE」を参照してください。HOLDLOCK は、指定されたテーブルやビューに対してのみ、また、使用されているステートメントによって定義されたトランザクションの間のみ適用されます。HOLDLOCK は、FOR BROWSE オプションを含む SELECT ステートメントでは使用できません。IGNORE_CONSTRAINTS
INSERT ステートメントで、BULK オプションが OPENROWSET と一緒に使用されているときにのみ適用できます。テーブルに対する制約を一括インポート操作時に無視することを指定します。既定では、INSERT によって CHECK 制約および FOREIGN KEY 制約がチェックされます。一括インポート操作の際に IGNORE_CONSTRAINTS を指定している場合、インポート対象のテーブルに対する制約が無視されます。UNIQUE、PRIMARY KEY、または NOT NULL の各制約を無効にすることはできません。
制約に違反する行が入力データに含まれている場合に、CHECK 制約および FOREIGN KEY 制約を無効化することができます。CHECK 制約および FOREIGN KEY 制約を無効化することによって、データをインポートしてから、Transact-SQL ステートメントを使用してデータをクリーンアップできます。
CHECK 制約および FOREIGN KEY 制約を無視すると、操作の後、テーブルに設定されている制約のうち、無視された制約は sys.check_constraints カタログ ビューまたは sys.foreign_keys カタログ ビューで is_not_trusted とマークされます。テーブル全体の制約は、任意の時点で必ず検証してください。一括インポート操作の前にテーブルが空白になっていない場合、制約の再検証にかかるコストは、CHECK 制約および FOREIGN KEY 制約を増分データに適用することによるコストを上回る可能性があります。
IGNORE_TRIGGERS
INSERT ステートメントで、BULK オプションが OPENROWSET と一緒に使用されているときにのみ適用できます。テーブルに対して定義されたトリガを、一括インポート操作時に無視することを指定します。既定では、INSERT はトリガを適用します。
アプリケーションがいずれのトリガにも依存しておらず、パフォーマンスの最大化が重要な場合にのみ、IGNORE_TRIGGERS を使用してください。
NOLOCK
READUNCOMMITTED に相当します。詳細については、後の「READUNCOMMITTED」を参照してください。注意 UPDATE ステートメントまたは DELETE ステートメントの場合 : この機能は、将来のバージョンの Microsoft SQL Server では削除される予定です。 新しい開発作業では、この機能の使用を避け、現在この機能を使用しているアプリケーションは修正するようにしてください。
NOWAIT
テーブルでロックがかかったらすぐにメッセージを返すようにデータベース エンジンを設定します。NOWAIT は、特定のテーブルに SET LOCK_TIMEOUT 0 を指定することに相当します。PAGLOCK
通常使用される行やキーに対する個々のロックまたは単一のテーブル ロックの代わりに、ページ ロックを使用します。既定では、操作に適したロック モードを使用します。SNAPSHOT 分離レベルで実行中のトランザクションにおいてこのオプションを指定しても、UPDLOCK や HOLDLOCK など、ロックが必要な他のテーブル ヒントと組み合わせて指定しない限り、ページ ロックは取得されません。READCOMMITTED
読み取り操作が、ロックまたは行バージョンを使用して、READ COMMITTED 分離レベルのルールに従うことを指定します。データベース オプション READ_COMMITTED_SNAPSHOT が OFF の場合、データベース エンジンはデータの読み取り時に共有ロックを取得し、読み取り操作が完了するとロックを解除します。データベース オプション READ_COMMITTED_SNAPSHOT が ON の場合、データベース エンジンはロックを取得せずに行バージョンを使用します。分離レベルの詳細については、「SET TRANSACTION ISOLATION LEVEL (Transact-SQL)」を参照してください。注意 UPDATE ステートメントまたは DELETE ステートメントの場合 : この機能は、将来のバージョンの Microsoft SQL Server では削除される予定です。 新しい開発作業では、この機能の使用を避け、現在この機能を使用しているアプリケーションは修正するようにしてください。
READCOMMITTEDLOCK
読み取り操作が、ロックを使用して、READ COMMITTED 分離レベルのルールに従うことを指定します。READ_COMMITTED_SNAPSHOT データベース オプションの設定にかかわらず、データベース エンジンはデータの読み取り時に共有ロックを取得し、読み取り操作が完了するとロックを解除します。分離レベルの詳細については、「SET TRANSACTION ISOLATION LEVEL (Transact-SQL)」を参照してください。READPAST
他のトランザクションによってロックされている行を、データベース エンジンが読み取らないことを指定します。多くの場合、この指定はページにも適用されます。READPAST を指定すると、行レベルとページレベルの両方のロックがスキップされます。つまり、データベース エンジンは、ロックが解除されるまで現在のトランザクションをブロックする代わりに、行やページをスキップします。たとえば、テーブル T1 に整数型の列が 1 つあり、値 1、2、3、4、5 が格納されているとします。このテーブルに対してトランザクション A で値 3 を 8 に変更し、この変更をまだコミットしていない間に SELECT * FROM T1 (READPAST) を実行すると、取得される値は 1、2、4、5 となります。READPAST は主に、SQL Server テーブルを使用する作業キューの実装時に、ロックの競合を減らすために使用します。READPAST を使用するキュー リーダーは、他のトランザクションによってロックされたキュー エントリを、ロックが解除されるまで待たずにスキップして、次に使用可能なキュー エントリへ進みます。READPAST は、UPDATE ステートメントまたは DELETE ステートメントで参照されるテーブル、および FROM 句で参照されるテーブルで指定できます。UPDATE ステートメントで READPAST を指定した場合、ステートメント内での指定場所にかかわらず、更新対象レコード特定のためのデータ読み取り時にだけ適用されます。INSERT ステートメントの INTO 句では、テーブルに READPAST を指定することができません。READPAST を使用する読み取り操作はブロックを行いません。READPAST を使用する更新操作や削除操作は、外部キーやインデックス付きビューの読み取り時、またはセカンダリ インデックスの変更時にブロックを行う場合があります。
READPAST は、READ COMMITTED 分離レベルまたは REPEATABLE READ 分離レベルで実行中のトランザクションでのみ指定できます。SNAPSHOT 分離レベルで実行中のトランザクションにおいてこのオプションを指定する場合、UPDLOCK や HOLDLOCK など、ロックが必要な他のテーブル ヒントと組み合わせて指定する必要があります。
READ_COMMITTED_SNAPSHOT データベース オプションが ON に設定され、次のいずれかの条件に該当する場合、READPAST テーブル ヒントは指定できません。
セッションのトランザクション分離レベルが READ COMMITTED の場合
READCOMMITTED テーブル ヒントもクエリで指定されている場合
このような場合に READPAST ヒントを指定するには、READCOMMITTED テーブル ヒントがある場合は削除し、クエリに READCOMMITTEDLOCK テーブル ヒントを含めます。
READUNCOMMITTED
ダーティ リードを許可することを指定します。現在のトランザクションによるデータ読み取りが他のトランザクションによって変更されないようにするため共有ロックを実行しません。また、他のトランザクションによって排他ロックが設定されていても、ロックされたデータの現在のトランザクションによる読み取りはブロックされません。ダーティ リードを許可すると同時実行性が高まりますが、他のトランザクションによってロールバックされているデータ変更を読み取る可能性があります。この結果、トランザクションでエラーが発生したり、コミットされていないデータがユーザーに提示されたり、レコードが重複表示されたりまったく表示されなかったりする場合があります。ダーティ リード、反復不能読み取り、およびファントム読み取りの詳細については、「同時実行の影響」を参照してください。READUNCOMMITTED ヒントと NOLOCK ヒントはデータのロックにのみ適用されます。READUNCOMMITTED ヒントおよび NOLOCK ヒントを含むクエリを含め、すべてのクエリは、コンパイル中と実行中にスキーマ安定度 (Sch-S) ロックを取得します。このため、同時実行トランザクションでテーブルに対するスキーマ修正 (Sch-M) ロックが保持されている場合、クエリはブロックされます。たとえば、データ定義言語 (DDL) 操作では、テーブルのスキーマ情報を変更する前にスキーマ修正 (Sch-M) ロックを取得します。READUNCOMMITTED ヒントまたは NOLOCK ヒントを指定して実行しているクエリを含め、すべての同時実行クエリは、スキーマ安定度 (Sch-S) ロックを取得しようとするとブロックされます。一方、スキーマ安定度 (Sch-S) ロックを保持するクエリによって、スキーマ修正 (Sch-M) ロックを取得しようとする同時実行トランザクションはブロックされます。ロックの動作の詳細については、「ロックの互換性 (データベース エンジン)」を参照してください。
READUNCOMMITTED および NOLOCK は、挿入、更新、削除の各操作によって変更されるテーブルに対しては指定できません。SQL Server クエリ オプティマイザは、UPDATE ステートメントまたは DELETE ステートメントの対象テーブルに適用する FROM 句内の READUNCOMMITTED ヒントおよび NOLOCK ヒントを無視します。
注意 FROM 句を UPDATE または DELETE ステートメントの対象テーブルに適用する場合、この句での READUNCOMMITTED ヒントおよび NOLOCK ヒントの使用は、将来のバージョンの SQL Server でサポートされなくなる予定です。新しい開発作業ではこのコンテキストでのヒントの使用を避け、現在このヒントを使用しているアプリケーションは変更を検討してください。
次のいずれかを使用することによって、ロックの競合を最小限に抑えながら、コミットされていないデータ変更のダーティ リードからトランザクションを保護することができます。
READ COMMITTED 分離レベル。READ_COMMITTED_SNAPSHOT データベース オプションを ON に設定します。
SNAPSHOT 分離レベル。
分離レベルの詳細については、「SET TRANSACTION ISOLATION LEVEL (Transact-SQL)」を参照してください。
注意 READUNCOMMITTED が指定されているときにエラー メッセージ 601 が表示された場合は、デッドロック エラー (1205) を解決するときと同じように解決し、ステートメントを再実行してください。
REPEATABLEREAD
REPEATABLE READ 分離レベルで実行しているトランザクションと同じロック セマンティクスでスキャンを実行することを指定します。分離レベルの詳細については、「SET TRANSACTION ISOLATION LEVEL (Transact-SQL)」を参照してください。ROWLOCK
通常取得されるページ ロックまたはテーブル ロックの代わりに、行ロックを取得することを指定します。SNAPSHOT 分離レベルで実行中のトランザクションにおいてこのオプションを指定しても、UPDLOCK や HOLDLOCK など、ロックが必要な他のテーブル ヒントと組み合わせて指定しない限り、行ロックは取得されません。SERIALIZABLE
HOLDLOCK に相当します。共有ロックがより制限的になります。テーブルまたはデータ ページが不要になったときに、トランザクションが完了しているかどうかにかかわらず共有ロックが解除されるのではなく、共有ロックはトランザクションが完了するまで保持されます。SERIALIZABLE 分離レベルで実行しているトランザクションと同じセマンティクスで、スキャンが実行されます。分離レベルの詳細については、「SET TRANSACTION ISOLATION LEVEL (Transact-SQL)」を参照してください。TABLOCK
テーブルに共有ロックを使用し、ステートメント終了まで保持することを指定します。HOLDLOCK も指定してある場合は、共有テーブル ロックがトランザクション終了まで保持されます。INSERT INTO <対象テーブル> SELECT <列> FROM <ソース テーブル> ステートメントを使用してデータをヒープにインポートするときに、対象テーブルに対して TABLOCK ヒントを指定すると、そのステートメントに対してログ記録とロックの最適化を有効にすることができます。データベース復旧モデルが単純復旧モデルまたは一括ログ復旧モデルに設定されている必要もあります。詳細については、「INSERT (Transact-SQL)」を参照してください。
テーブルにデータをインポートするため、OPENROWSET 一括行セット プロバイダで TABLOCK を使用すると、対象テーブルへのデータ読み込みを、ログ記録とロックを最適化して、複数のクライアントで同時に行うことができます。詳細については、「一括インポートで最小ログ記録を行うための前提条件」を参照してください。
TABLOCKX
テーブルに排他ロックを使用することを指定します。UPDLOCK
更新ロックを使用することと、これをトランザクション終了まで保持することを指定します。XLOCK
排他ロックを使用することと、これをトランザクション終了まで保持することを指定します。ROWLOCK、PAGLOCK、または TABLOCK と組み合わせて指定すると、排他ロックは適切な粒度レベルに適用されます。
説明
テーブルがクエリ プランによってアクセスされているのではない場合、テーブル ヒントは無視されます。これは、オプティマイザがテーブルにまったくアクセスしないことを選択した結果であるか、またはインデックス付きビューが代わりにアクセスされるためである可能性があります。後者の場合、OPTION (EXPAND VIEWS) クエリ ヒントを使用することで、インデックス付きビューへのアクセスを防ぐことができます。
すべてのロック ヒントが、クエリ プランによってアクセスされているすべてのテーブルおよびビュー (ビューで参照されているテーブルおよびビューを含む) に反映されます。また、SQL Server は、対応するロックの一貫性チェックを実行します。
行レベルのロックを取得するロック ヒント ROWLOCK、UPDLOCK、および XLOCK では、実際のデータ行ではなくインデックス キーに対してロックが実行される場合があります。たとえば、テーブルに非クラスタ化インデックスがあり、ロック ヒントを使用する SELECT ステートメントがカバーするインデックスによって処理される場合、ベース テーブルのデータ行ではなく、カバーするインデックスのインデックス キーに対してロックが取得されます。
テーブルに計算列があり、その計算列が、別のテーブル内の列にアクセスする式や関数によって計算される場合、そのテーブル上でテーブル ヒントが使用されることはありません。つまり、テーブル ヒントは反映されません。たとえば、クエリ内のテーブルに NOLOCK テーブル ヒントが指定されているものとします。このテーブルには、別のテーブル内の列にアクセスする式と関数の組み合わせで計算される、計算列があります。式と関数で参照されるテーブルが、アクセスされるときに NOLOCK テーブル ヒントを使用することはありません。
SQL Server では、FROM 句内の各テーブルに対して、次の各グループの複数のテーブル ヒントが許可されません。
粒度ヒント : PAGLOCK、NOLOCK、ROWLOCK、TABLOCK、TABLOCKX
分離レベル ヒント : HOLDLOCK、NOLOCK、READCOMMITTED、REPEATABLEREAD、SERIALIZABLE
フィルタ選択されたインデックス ヒント
フィルタ選択されたインデックスをテーブル ヒントとして使用できますが、クエリで選択する行のすべてがカバーされているわけではない場合、クエリ オプティマイザからエラー 8622 が返されます。フィルタ選択されたインデックス ヒントが無効になる例を次に示します。この例では、フィルタ選択されたインデックス FIBillOfMaterialsWithComponentID を作成し、SELECT ステートメントのインデックス ヒントとして使用します。フィルタ選択されたインデックスの述語には、ComponentID が 533、324、および 753 のデータ行が含まれています。クエリ述語にも ComponentID が 533、324、および 753 のデータ行が含まれていますが、フィルタ選択されたインデックスには存在しない ComponentID 855 および 924 も結果セットに含めるよう拡張されています。したがって、クエリ オプティマイザはフィルタ選択されたインデックス ヒントを使用できず、エラー 8622 が生成されます。詳細については、「フィルタ選択されたインデックスのデザイン ガイドライン」を参照してください。
USE AdventureWorks;
GO
IF EXISTS (SELECT name FROM sys.indexes
WHERE name = N'FIBillOfMaterialsWithComponentID'
AND object_id = OBJECT_ID(N'Production.BillOfMaterials'))
DROP INDEX FIBillOfMaterialsWithComponentID
ON Production.BillOfMaterials;
GO
CREATE NONCLUSTERED INDEX "FIBillOfMaterialsWithComponentID"
ON Production.BillOfMaterials (ComponentID, StartDate, EndDate)
WHERE ComponentID IN (533, 324, 753);
GO
SELECT StartDate, ComponentID FROM Production.BillOfMaterials
WITH( INDEX (FIBillOfMaterialsWithComponentID) )
WHERE ComponentID in (533, 324, 753, 855, 924);
GO
フィルタ選択されたインデックスに必要な値が SET オプションにない場合、クエリ オプティマイザはインデックス ヒントを無視します。詳細については、「CREATE INDEX (Transact-SQL)」を参照してください。
NOEXPAND の使用
NOEXPAND はインデックス付きビューにのみ適用できます。インデックス付きビューとは、一意なクラスタ化インデックスが作成されているビューを示します。インデックス付きビューおよびベース テーブルの両方に存在する列への参照がクエリに含まれていて、クエリ オプティマイザがクエリの実行にインデックス付きビューを使用する方が最適であると判断した場合、クエリ オプティマイザはビューのインデックスを利用します。この機能は、インデックス付きビューのマッチングと呼ばれ、SQL Server の Enterprise Edition および Developer Edition でのみサポートされています。
ただし、オプティマイザで、インデックス付きビューのマッチングを検討したり、NOEXPAND ヒントで参照されるインデックス付きビューを使用したりするには、以下の SET オプションを ON に設定する必要があります。
ANSI_NULLS |
ANSI_WARNINGS |
CONCAT_NULL_YIELDS_NULL |
ANSI_PADDING |
ARITHABORT1 |
QUOTED_IDENTIFIERS |
1 ARITHABORT は、ANSI_WARNINGS が ON に設定されている場合は、暗黙的に ON に設定されます。したがって、この設定を手動で調整する必要はありません。
また、NUMERIC_ROUNDABORT オプションは OFF に設定する必要があります。
オプティマイザがインデックス付きビューのインデックスを使用するように強制するには、NOEXPAND オプションを指定します。このヒントは、ビューがクエリ内でも指定されている場合にのみ使用できます。SQL Server では、FROM 句で直接ビューを指定していないクエリで、特定のインデックス付きビューが使用されるようにするヒントは用意されていません。しかし、クエリ オプティマイザでは、インデックス付きビューがクエリで直接参照されていなくても、その使用が検討されます。
詳細については、「ビューのインデックスの解決」を参照してください。
クエリ ヒントとしてのテーブル ヒントの使用
OPTION (TABLE HINT) 句を使用すると、テーブル ヒントをクエリ ヒントとして指定することもできます。プラン ガイドのコンテキスト内でのみ、テーブル ヒントをクエリ ヒントとして使用することをお勧めします。アドホック クエリに対しては、これらのヒントをテーブル ヒントとしてのみ指定します。詳細については、「クエリ ヒント (Transact-SQL)」を参照してください。
権限
KEEPIDENTITY、IGNORE_CONSTRAINTS、IGNORE_TRIGGERS の各ヒントには、テーブルに対する ALTER 権限が必要です。
例
A. TABLOCK ヒントを使用したロック手法の指定
次の例では、Production.Product テーブルに対して共有ロックを使用することと、このロックを UPDATE ステートメントの終了まで保持することを指定します。
USE AdventureWorks;
GO
UPDATE Production.Product
WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK-%';
GO
B. FORCESEEK ヒントを使用したインデックスのシーク操作の指定
次の例では、FORCESEEK ヒントを使用して、Sales.SalesOrderDetail テーブルに対するインデックスのシーク操作を実行するようにクエリ オプティマイザを設定します。
USE AdventureWorks;
GO
SELECT *
FROM Sales.SalesOrderHeader AS h
INNER JOIN Sales.SalesOrderDetail AS d WITH (FORCESEEK)
ON h.SalesOrderID = d.SalesOrderID
WHERE h.TotalDue > 100
AND (d.OrderQty > 5 OR d.LineTotal < 1000.00);
GO