我有一個SQL Server 2014的實例。到主數據庫中,我創建了一些用戶定義的函數,以便簡化使用期間的查詢。 NET應用程序。SQL Server 2014-內存泄漏和巨大的CPU使用用戶定義的函數內的變量
我在特定函數中遇到了內存和性能問題。這是我正在使用的功能:
ALTER FUNCTION [dbo].[getNotificationInspections](
@range int = 3
)
RETURNS
@Notifies TABLE
(
min_id_history int,
max_id_history int,
disCounter tinyint,
name_job varchar(15),
desc_job varchar(150),
id_inspect smallint,
pc_host varchar(15),
name_inspect varchar(10),
link_image varchar(100)
)
AS
BEGIN
DECLARE @minHistory int
DECLARE @maxHistory int
SELECT @minHistory = minHistory,
@maxHistory = maxHistory
FROM getLastEngineRange(@range)
--SELECT @minHistory, @macHistory
INSERT @Notifies
SELECT @minHistory min_id_history, @macHistory max_id_history, DS.*
FROM dbo.RealDiscardRange(@minHistory, @maxHistory) DS
WHERE DS.disCounter = @range
RETURN
END
此功能工作正常,除了它需要約4-5秒和約1.5Gb的內存! 3排!但讓我們繼續看看發生了什麼。
如果我執行定義@maxHistory唯一的查詢和@minHistory它不使用CPU或時間或內存。
如果我使用「使用的值,而不是變量」的INSERT @Notifies查詢它花費200ms左右,無記憶!
因此,在查詢中使用變量需要巨大的CPU和內存!
事實上,如果我用這個查詢出來的功能,但作爲一個簡單的查詢:
INSERT @Notifies
EXEC('SELECT min_id_history=''' + @minHistory + ''',
max_id_history=''' + @maxHistory + ''', DS.*
FROM dbo.RealDiscardRange(' + @minHistory + ', ' + @maxHistory + ') DS
WHERE DS.disCounter = ' + @range + ' ')
RETURN
的時間和內存spended執行這個人是可以忽略不計。每次SQL Server服務時都會重新啓動這些測試。
我希望有人能解釋這一點。
我認爲,它與你的問題中的錯字沒有關係?你在返回的SELECT語句中有macHistory而不是maxHistory? –
最有可能是次優執行計劃而不是內存泄漏。 SQL Server緩存數據,直到檢測到內存壓力時才釋放內存。不理想的計劃會觸及更多的數據,並因此使用更多緩存。 –
你如何測量內存消耗?請發佈執行計劃。 –