這是查詢的只是一部分,但它似乎是瓶頸:我需要幫助提高我的SQL查詢拉最近的一份文件數
SELECT CAST (CASE WHEN EXISTS
(SELECT 1
FROM dbo.CBDocument
WHERE (FirmId = R.FirmId) AND
(ContributionDate > DATEADD(m, -3, GETDATE())) AND
((EntityTypeId = 2600 AND EntityId = P.IProductId) OR
(EntityTypeId = 2500 AND EntityId = M.IManagerId)))
THEN 1 ELSE 0 END AS BIT) AS HasRecentDocuments
FROM dbo.CBIProduct P
JOIN dbo.CBIManager M ON P.IManagerId = M.IManagerId
JOIN dbo.CBIProductRating R ON P.IProductId = R.IProductId
JOIN dbo.CBIProductFirmDetail D ON (D.IProductId = P.IProductId) AND
(R.FirmId = D.FirmId)
CROSS APPLY (SELECT TOP 1 RatingDate, IProductRatingId, FirmId
FROM dbo.CBIProductRating
WHERE (IProductId = P.IProductId) AND (FirmId = R.FirmId)
ORDER BY RatingDate DESC) AS RD
WHERE (R.IProductRatingId = RD.IProductRatingId) AND (R.FirmId = RD.FirmId)
有很多其他列的,我通常拉回需要CROSS APPLY和其他連接。我需要優化的位是case語句中的子查詢。這個子查詢需要3分鐘才能返回119k條記錄。我對SQL知之甚少,但必須有一種方法來提高效率。
查詢的要點就是返回一個標誌,如果相關產品已被添加到系統中的最後3個月內的任何文件。
編輯:我的數據庫託管在Azure中,數據庫優化顧問將不會連接到它。 Azure中有一個調優顧問組件,但它沒有提供任何建議。必須有更好的方法來查詢。
編輯:在試圖進一步簡化和確定的罪魁禍首,我又縮減到這個查詢:(而不是確定一個最近的文檔存在,它只是計算最近的文檔)。
SELECT D.FirmId, P.IProductId,
,(SELECT COUNT(DocumentId) FROM dbo.CBDocument WHERE
(FirmId = D.FirmId) AND
(ContributionDate > DATEADD(m, -3, GETDATE())) AND
((EntityTypeId = 2600 AND EntityId = P.IProductId) OR
(EntityTypeId = 2500 AND EntityId = M.IManagerId))) AS RecentDocCount
FROM dbo.CBIProduct P
FULL JOIN dbo.CBIProductFirmDetail D ON D.IProductId = P.IProductId
JOIN dbo.CBIManager M ON M.IManagerId = P.IManagerId
那運行3分53秒。
如果我聲明一個變量來存儲日期(DECLARE @Today DATE = GETDATE()
) 並在查詢(DATEADD(m, -3, @Today)
)把變量到位GETDATE()的,它運行在12秒內。
是否與GETDATE一個已知的性能問題()?據我所知,我不能在視圖定義中使用該變量。
這是否對任何可能指向解決方案的東西閃耀光芒?我想我可以把整個事情變成一個存儲過程,但是我也必須調整應用程序代碼。
謝謝。
https://docs.microsoft.com/en-us/sql/tools/dta/tutorial-database-engine-tuning-advisor做到這一點,你可能會很幸運,只需添加一些新索引 – Will
謝謝@Will。我一直在那條路上。我無法將DTA連接到Azure中的數據庫,Azure的調優顧問不推薦任何內容。 –
如果你可以阻止數據庫,並將其加載到本地sql服務器實例,你仍然可以嘗試。我相信,索引在蔚藍的天空中不會有所不同。 – Will