以下のクエリでFORCESEEKヒントを使用しようとすると、次のエラーが発生します。
メッセージ8622、レベル16、状態1、行96このクエリでヒントが定義されているため、クエリプロセッサはクエリプランを作成できませんでした。ヒントを指定せず、SET FORCEPLANを使用せずにクエリを再送信します。
SELECT A.IndexedField1
INTO #TEMP
FROM dbo.IndexedView1 AS A WITH (FORCESEEK)
INNER JOIN dbo.IndexedView2 AS B
ON A.IndexedField1 = B.IndexedField1
AND A.IndexedField2 = B.IndexedField2
IndexedView1とIndexedView2はどちらもスキーマバインドされたインデックス付きビューであり、IndexedField1、IndexedField2フィールドの両方のビューに一意のクラスター化インデックスがあります。適切かどうかはわかりませんが、クラスター化インデックスのサイズは40バイト(1行あたり)です。
両方のビューが実際にどのように見えるかの例を以下に示します。
SELECT
IndexedField1,
RIGHT(CONVERT(VARCHAR(34), HASHBYTES('MD5', OtherField1 + '||' OtherField2)), 32) AS IndexedField2
FROM dbo.Table1
派手すぎず、ビューのクエリ内にヒントもありません。
これが再現です。 [documented[〜#〜] noexpand [〜#〜] がないと、インデックス付きビューでFORCESEEKを使用できません。
例えば
drop table if exists table1
drop table if exists table2
go
create table Table1(IndexedField1 int, OtherField1 nvarchar(200), OtherField2 nvarchar(200))
create table Table2(IndexedField1 int, OtherField1 nvarchar(200), OtherField2 nvarchar(200))
go
create view IndexedView1
with schemabinding
as
SELECT
IndexedField1,
RIGHT(CONVERT(VARCHAR(34), HASHBYTES('MD5', OtherField1 + '||' + OtherField2)), 32) AS IndexedField2
FROM dbo.Table1
go
create view IndexedView2
with schemabinding
as
SELECT
IndexedField1,
RIGHT(CONVERT(VARCHAR(34), HASHBYTES('MD5', OtherField1 + '||' + OtherField2)), 32) AS IndexedField2
FROM dbo.Table2
go
create unique clustered index pk_IndexedView1 on IndexedView1(IndexedField1,IndexedField2)
create unique clustered index pk_IndexedView2 on IndexedView2(IndexedField1,IndexedField2)
go
SELECT A.IndexedField1
INTO #TEMP
FROM dbo.IndexedView1 AS A WITH (FORCESEEK)
INNER JOIN dbo.IndexedView2 AS B
ON A.IndexedField1 = B.IndexedField1
AND A.IndexedField2 = B.IndexedField2
/*
Msg 8622, Level 16, State 1, Line 34
Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query without specifying any hints and without using SET FORCEPLAN.
*/
go
drop table if exists #TEMP
SELECT A.IndexedField1
INTO #TEMP
FROM dbo.IndexedView1 AS A with (noexpand)
INNER JOIN dbo.IndexedView2 AS B with (noexpand)
ON A.IndexedField1 = B.IndexedField1
AND A.IndexedField2 = B.IndexedField2
プランで実行:
さらに、NOEXPANDを適用し、プランにビューインデックスのみが含まれるように指定した後、FORCESEEKヒントを使用するか、必要に応じて結合スタイル(MERGE、LOOP、またはHASH)を指定できます。
例えば
SELECT A.IndexedField1
INTO #TEMP
FROM dbo.IndexedView1 AS A WITH (NOEXPAND)
INNER MERGE JOIN dbo.IndexedView2 AS B
ON A.IndexedField1 = B.IndexedField1
AND A.IndexedField2 = B.IndexedField2