下面有一個簡單的SQL語句JOIN
:爲什麼這個SQL查詢需要8個小時才能完成?
SELECT
REC.[BarCode]
,REC.[PASSEDPROCESS]
,REC.[PASSEDNODE]
,REC.[ENABLE]
,REC.[ScanTime]
,REC.[ID]
,REC.[Se_Scanner]
,REC.[UserCode]
,REC.[aufnr]
,REC.[dispatcher]
,REC.[matnr]
,REC.[unitcount]
,REC.[maktx]
,REC.[color]
,REC.[machinecode]
,P.PR_NAME
,N.NO_NAME
,I.[inventoryID]
,I.[status]
FROM tbBCScanRec as REC
left join TB_R_INVENTORY_BARCODE as R
ON REC.[BarCode] = R.[barcode]
AND REC.[PASSEDPROCESS] = R.[process]
AND REC.[PASSEDNODE] = R.[node]
left join TB_INVENTORY as I
ON R.[inventid] = I.[id]
INNER JOIN TB_NODE as N
ON N.NO_ID = REC.PASSEDNODE
INNER JOIN TB_PROCESS as P
ON P.PR_CODE = REC.PASSEDPROCESS
表tbBCScanRec
有556553條記錄,而表TB_R_INVENTORY_BARCODE
有260513個reccords和表TB_INVENTORY
有7688.不過,最後兩個表(TB_NODE
和TB_PROCESS
)都少於30個記錄。令人難以置信的是,它在SQL Server 2005中運行時,需要8小時才能返回結果集。
爲什麼需要很長時間來執行?
如果兩個inner join
被刪除,則只需十秒鐘即可完成運行。
這是怎麼回事?
有至少兩個UNIQUE NONCLUSTERED INDEX
es。
一個是IX_INVENTORY_BARCODE_PROCESS_NODE
在桌子上TB_R_INVENTORY_BARCODE
,其覆蓋四列(inventid
,barcode
,process
,和node
)。
另一種是IX_BARCODE_PROCESS_NODE
在桌子上tbBCScanRec
,它覆蓋三列(BarCode
,PASSEDPROCESS
,和PASSEDNODE
)。
我不能推薦任何具體的教程,但你需要學習理解執行計劃。在SSMS中有一些選項可以打開執行計劃 - 如果你可以補充一下,我們可能會給你一些指示(儘管發佈一個XML查詢計劃,儘管如此)。此外,通常使用實際值而不是預計值計劃更好,但如果預計需要8小時才能獲得實際值,則預計計劃可能已足夠。 –