我試圖在大表中找到所有相關記錄並基於較小的記錄集更新它們,但只要我這樣做,所有的性能就會從窗口中消失,開始做一個巨大的桌子全表掃描。防止使用臨時表進行全表掃描
下面的表會是什麼樣子導入文件3之後的示例(有上VoidID列名和文件名以及索引)
該表顯示,ID#1與ID#2反之亦然,對於ID#4和#5也是如此。 ID#3是一個沒有空缺的銷售。
在導入File3後,我想查找所有記錄,在同一個文件中有銷售和空白,但僅限於剛導入的文件。所以,我使用的是臨時表#Results這裏我只插入來自文件3的ID的,但是當我補充一點,臨時表到查詢,它的表的全掃描和需要永遠運行:
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
這可行,但全表掃描現在仍在運行(超過一個小時),所以這是不可接受的。估計的執行計劃顯示沒有缺失索引。
如何改進此查詢?
**編輯實際的查詢,Key和指數**
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