大きなテーブルのすべての関連レコードを見つけて、それを小さなレコードセットに基づいて更新しようとしていますが、すぐにすべてのパフォーマンスがウィンドウに表示され、大規模なテーブルの完全なテーブルスキャンを開始します。以下テーブル全体のスキャンを行う一時テーブルとの結合を防止する
テーブルはFILE3をインポートした後にどのように見えるかの例である(VoidID列とファイル名のインデックスが同様にあります)
テーブルは、ID#1はID#2に関連して表示されているとID#4と#5と同じです。 ID#3は無効な売却です。
File3をインポートした後、同じファイルに販売と無効が存在するが、インポートされたばかりのファイルについてのみ、すべてのレコードを探したいとします。だから私は、私だけFILE3からIDを挿入する一時テーブル#Resultsを使用していますが、私は、クエリにその一時テーブルを追加するとき、それはテーブルのフルスキャンを行い、実行するために永遠に取ります
DECLARE @Import Table(ID int PRIMARY KEY NOT NULL, TransType varchar(10), VoidID int, FileName varchar(25))
INSERT INTO @Import
VALUES(1,'Sale',2,'File1'),(2,'Void',1,'File1'),(3,'Sale',NULL,'File2'),(4,'Sale',5,'File3'),(5,'Void',4,'File3')
SELECT * FROM @Import
CREATE table #Results(ID integer PRIMARY KEY NOT NULL)
INSERT INTO #Results(ID)
SELECT ID FROM @Import WHERE FileName = 'File3'
select * from #Results
SELECT P1.ID
FROM @Import P1 INNER JOIN #Results R ON P1.ID = R.ID INNER JOIN @Import P2 ON P1.ID = P2.VoidID
WHERE P1.FileName = P2.FileName
DROP TABLE #Results
これは動作しますが、フルテーブルスキャンは今でも(1時間以上)実行されているので、実際には受け入れられません。推定された実行計画には、欠落しているインデックスはありません。
このクエリを改善するにはどうすればよいですか?
** EDIT実際のクエリ、キー、およびインデックス**
UPDATE P1
SET Notes = 'Matching Sale, Void in same file.'
FROM
PriceImport P1 INNER JOIN
#ResultSet R ON P1.ID = R.ID INNER JOIN
PriceImport P2 ON P1.ID = P2.VoidID
WHERE P1.FileName = P2.FileName
ALTER TABLE [dbo].[PriceImport] ADD CONSTRAINT [PK_PriceImportID] PRIMARY KEY NONCLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [idx_PriceImport_Transaction_Matching] ON [dbo].[PriceImport]
(
[TransType] ASC,
[VoidID] ASC
)
INCLUDE ([ID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
実行計画を見て、テーブルスキャンの原因を調べてみてください。あなたは、テーブルまたは一時テーブルにインデックスがありませんか? –
'EXCEPTS'構文を見るのも有益でしょう。場合によっては、より高速になる可能性があります。 – Shaneis
あなたは本当に 'WHERE P1.FileName = P2.FileName'を必要とします – JamieD77