Sql-Server
曾經很快的慢標量函式
我有一個標量函式,定義如下:
CREATE FUNCTION GetUserFullname(@Id INT) RETURNS NVARCHAR(500) AS BEGIN -- Declare the return variable here DECLARE @fullname NVARCHAR(500) -- Add the T-SQL statements to compute the return value here SELECT @fullname = (Firstname + ' ' + Lastname) FROM Account_Profiles WHERE UserId = @Id -- Return the result of the function RETURN @fullname END
當我在查詢中使用此功能時,它曾經很快:
SELECT dbo.GetUserFullname(CurrentRefId) FROM OrderItems
上面的查詢有大約 50,000 行的結果。查詢曾經在 2 秒內執行,但現在突然需要 22 秒才能執行!
當我查詢時,所有不同的
CurrentRefId
in值都很慢。每晚都會更新統計數據。還有一個 Total Fragmentation 75 的索引。OrderItems``SELECT dbo.GetUserFullname(CurrentRefId) FROM OrderItems
我在我的本地 SQL Server 中也有這個數據庫的副本,它在大約 1 秒內執行得非常快。
我的生產數據庫伺服器有 512 GB 記憶體和 64 個處理器。它是一個 Always On 故障轉移群集伺服器和可用性組。數據庫版本為 2012 SP2。
您正在為 OrderItems 中的每一行重新查詢 Account_Profiles 表。如果 OrderItems 有 50,000 行,那麼您將點擊 Account_Profiles 50,000 次。如果 OrderItems 變大,您將查詢更多次。如果 Account_Profiles 變得更大,那麼每個時間都將花費更長的時間。通過內聯串聯,您會看到很大的不同。(在這裡對連接列名進行假設)
Select Firstname + ' ' + Lastname FullName --other data here FROM OrderItems oi INNER JOIN Account_Profiles ap ON oi.userid=ap.userid
慢速伺服器上是否執行了跟踪或擴展事件?有人遇到了類似的問題,這最終成為了根本原因。
否則,您可以通過將該標量 UDF 重寫為表值函式或根本不使用該函式來永久解決該問題。