[英]SQL Server query suddenly slow
我有一個SQL數據庫查詢的問題突然 (但通常大約每三周)變得緩慢。
安裝程序如下:
Orders
)主要是從大約24000條記錄中選擇的,其他5條連接表都很小(100條記錄以下) Orders
有一個varbinary(MAX)
列Report
,其中包含平均大小約為200到300 kB的二進制數據(PDF文檔)(偶爾可以高達2 MB)。 這24000個訂單中有90%以上填充了此列,其他訂單為NULL
,即6 GB數據庫大小的90%以上是二進制數據。 有問題的查詢具有以下結構:
SELECT TOP (30) [Project2].[OrderID] AS [OrderID]
-- around 20 columns more
FROM ( SELECT [Project2].[OrderID] AS [OrderID],
-- around 20 columns more
row_number() OVER (ORDER BY [Project2].[OrderID] ASC) AS [row_number]
FROM ( SELECT [Filter1].[OrderID] AS [OrderID]
-- around 20 columns more
FROM ( SELECT [Extent1].[OrderID] AS [OrderID]
-- around 20 columns more
FROM [dbo].[Orders] AS [Extent1]
INNER JOIN -- small table
LEFT OUTER JOIN -- small table
LEFT OUTER JOIN -- small table
LEFT OUTER JOIN -- small table
LEFT OUTER JOIN -- small table
WHERE ([Extent1].[Status] IS NOT NULL)
AND (4 = CAST( [Extent1].[Status] AS int))
AND ([Extent1].[SomeDateTime] IS NULL)
AND ([Extent1].[Report] IS NULL)
) AS [Filter1]
OUTER APPLY (SELECT TOP (1) [Project1].[C1] AS [C1]
FROM ( SELECT CAST( [Extent7].[CreationDateTime] AS datetime2) AS [C1],
[Extent7].[CreationDateTime] AS [CreationDateTime]
FROM [dbo].[OtherTable] AS [Extent7]
WHERE [Filter1].[OrderID] = [Extent7].[OrderID]
) AS [Project1]
ORDER BY [Project1].[CreationDateTime] DESC
) AS [Limit1]
) AS [Project2]
) AS [Project2]
WHERE [Project2].[row_number] > 0
ORDER BY [Project2].[OrderID] ASC
它是由Entity Framework從LINQ到實體查詢生成的。 查詢發生在一些變體中,這些變體僅在第一個WHERE
子句中有所不同:
五個變種
WHERE ([Extent1].[Status] IS NOT NULL) AND (X = CAST( [Extent1].[Status] AS int))
X可以在0
到4
之間。 這些查詢從來都不是問題。
這兩個變種(*)
WHERE ([Extent1].[Status] IS NOT NULL) AND (4 = CAST( [Extent1].[Status] AS int)) AND ([Extent1].[SomeDateTime] IS NULL) AND ([Extent1].[Report] IS NULL)
或者... IS NOT NULL...
在最后一行。 我只有這兩個查詢才會遇到下面描述的問題。
“現象”是:
另外一個觀察:
不知怎的,我懷疑整個問題與Express版本和varbinary(MAX)
列的內存限制(1 GB)有關,盡管我只是在WHERE
子句中使用它來檢查列值是NULL
還是非NULL
。 “ Report
列本身不是所選列之一。
由於我正在運行明年Express版本的限制(10 GB mdf文件大小),我正在考慮更改:
Orders
表中 問題:查詢突然變慢的原因是什么? 我計划的其中一項變更可以解決問題還是有其他解決方案?
編輯
在下面的評論中按照bhamby的提示,我在SSMS中設置了SET STATISTICS TIME ON
,然后再次運行查詢。 當查詢再次變慢時,我得到SQL Server parse and compile time
的高值,即: CPU time = 27,3 sec
, Elapsed time = 81,9 sec
。 查詢的執行時間僅為CPU時間= 0,06秒,經過時間= 2,8秒。 在此之后第二次運行查詢,為SQL Server解析和編譯時間提供CPU時間0,06秒和經過時間= 0,08。
這看起來很浪費
SELECT TOP (1) [Project1].[C1] AS [C1]
FROM ( SELECT CAST( [Extent7].[CreationDateTime] AS datetime2) AS [C1],
[Extent7].[CreationDateTime] AS [CreationDateTime]
FROM [dbo].[OtherTable] AS [Extent7]
WHERE [Filter1].[OrderID] = [Extent7].[OrderID]
) AS [Project1]
ORDER BY [Project1].[CreationDateTime] DESC
是
SELECT max( CAST( [Extent7].[CreationDateTime] AS datetime2) ) AS [C1]
FROM [dbo].[OtherTable] AS [Extent7]
WHERE [Filter1].[OrderID] = [Extent7].[OrderID]
為什么不將日期存儲為日期時間?
我不喜歡那種外在的申請
我會創建一個運行一次的#temp並加入它
確保並將[OrderID]聲明為PK
SELECT [Extent7].[OrderID], max( CAST( [Extent7].[CreationDateTime] AS datetime2) ) AS [C1]
FROM [dbo].[OtherTable] AS [Extent7]
GROUP BY [Extent7].[OrderID]
你可以進行循環連接
接下來我會把它放在#temp2中,這樣你就可以確定它只運行一次
再次確保將OrderID聲明為PK
SELECT [Extent1].[OrderID] AS [OrderID]
-- around 20 columns more
FROM [dbo].[Orders] AS [Extent1]
INNER JOIN -- small table
LEFT OUTER JOIN -- small table
LEFT OUTER JOIN -- small table
LEFT OUTER JOIN -- small table
LEFT OUTER JOIN -- small table
WHERE ([Extent1].[Status] IS NOT NULL)
AND (4 = CAST( [Extent1].[Status] AS int))
AND ([Extent1].[SomeDateTime] IS NULL)
AND ([Extent1].[Report] IS NULL)
如果訂單只有24,000行,那么你會有一些愚蠢的事情讓你查詢超過幾秒鍾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.