我是一家醫療自動化公司的DBA。我們有1個客戶正在使用我們的應用程序,這位客戶是1400名客戶中唯一受到影響的客戶。在隨機時間,有一個需要HOURS運行的存儲過程。我自己和另一位數據庫管理員在他們提出問題時一直在進行故障排除和診斷,但它又一次發生,我們感到有些不知所措。長時間運行程序
我相信當它進入這個「車轍」時,這是因爲緩存的執行計劃不好。我接下來要做的是爲該存儲過程運行一個SP_Recompile,並讓它每次重新編譯,但是誰又說是不是再次緩存壞計劃。我添加了MAXDOPS,因爲我們認爲這可能是一個並行的問題,但這些都沒有幫助。
我們將其縮小到一個「步驟」,我們創建了一個調試數據庫來捕獲數據。通常這一步不到5分鐘即可完成。它現在需要大約4-5個小時。我在代碼的下面包含了TSQL片段。任何建議,批評,或平坦的幫助非常感謝!謝謝!
insert into DBAdiag.dbo.dumbcodedebug (note, createddate)
values ('PatientAuditLog Insert Start',getdate())
SET @StartTime = GETUTCDATE();
SET IDENTITY_INSERT [XTArchive].dbo.PatientAuditLog ON;
INSERT INTO [XTArchive].dbo.PatientAuditLog (a.[PatientAuditLogID],a.[PatientHistoryCrossRefID],a.[PatientFieldNameTypeID],a.[OldValue],a.[NewValue],a.[CreatedDate])
SELECT a.[PatientAuditLogID],a.[PatientHistoryCrossRefID],a.[PatientFieldNameTypeID],a.[OldValue],a.[NewValue],a.[CreatedDate] FROM dbo.PatientAuditLog a WITH (NOLOCK)
LEFT JOIN [XTArchive].dbo.PatientAuditLog b on b.PatientAuditLogID = a.PatientAuditLogID
WHERE a.CreatedDate <= @ArchiveProcessStartTime AND b.PatientAuditLogID IS NULL
AND EXISTS(SELECT 1 FROM [XTArchive].dbo.PatientHistoryCrossRef e1 where e1.PatientHistoryCrossRefID = a.PatientHistoryCrossRefID)
option (maxdop 6)
SELECT @RowCount = @@ROWCOUNT;
SET IDENTITY_INSERT [XTArchive].dbo.PatientAuditLog OFF;
PRINT N'Insert into PatientAuditLog;' + convert(varchar(11), @StartTime, 101) + ' ' + convert(varchar(13),@StartTime,114) + ';' + convert(varchar(11), getutcdate(), 101) + ' ' + convert(varchar(13),getutcdate(),114) + ';' + CAST(@RowCount AS VARCHAR(10)) + ';' + 'PatientAuditLog' + ';' + '530'
insert into DBAdiag.dbo.dumbcodedebug (note, createddate)
values ('PatientAuditLog Insert end',getdate())
您可以完全停用計劃緩存。最簡單的方法是在映射到參數的proc中定義虛擬變量。 https://www.mssqltips.com/sqlservertip/3257/different-approaches-to-correct-sql-server-parameter-sniffing/ – bic
既然你說你爲一家醫療保健公司工作,你可能想要檢查你是否應該全部使用NOLOCK。你確定丟失和/或重複的行嗎? http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/ –