Dot-Net

LINQ 呼叫儲存過程很慢

  • February 20, 2013

當然,一切都是相對的,但與簡單地使用查詢管理器執行相同的 SQL 相比,還是有很大的不同。

我使用分析器查看了當 LINQ 呼叫儲存過程時數據庫執行了哪些 SQL 語句。結果在大約 1400 毫秒內返回,如果我複制/粘貼 SQL 並通過查詢管理器執行完全相同的 SQL,則結果在 2 毫秒內返回。這讓我想知道是否有什麼我需要做的?這裡有沒有人有過類似的經歷?

以下是從 LINQ 發送的 SQL:

declare @p26 int
set @p26=0
exec sp_executesql N'EXEC @RETURN_VALUE = [dbo].[TapeInfo_Get] @TapeFlag_IsDigitized = @p0, @TapeFlag_ChosenSingleTape = @p1, @TapeFlag_ChosenHierarchy = @p2, @TapeFlag_ChosenForced = @p3, @TapeFlag_ExcludedHierarchy = @p4, @TapeFlag_ExcludedARKBNR = @p5, @TapeFlag_ExcludedForced = @p6, @TapeFlag_ExcludedFilmRoll = @p7, @TapeFlag_ExcludedDVCPRO = @p8, @TapeFlag_ExcludedVHS = @p9, @TapeFlag_ExcludedType = @p10, @TapeFlag_NoticeBNR = @p11, @TapeFlag_NoticeMultiplePNR = @p12, @TapeFlag_NoticeType = @p13, @ProductionFlag_ExcudedDate = @p14, @ProductionFlag_NoticeMultipleTape = @p15, @ProductionFlag_NoticeFilm1C = @p16, @ProductionFlag_NoticeFilmBetaDigial = @p17, @ProductionFlag_ExcludedForeignProd = @p18, @Query = @p19, @PageIndex = @p20, @PageSize = @p21, @ReturnCount = @p22',N'@p0 bit,@p1 bit,@p2 bit,@p3 bit,@p4 bit,@p5 bit,@p6 bit,@p7 bit,@p8 bit,@p9 bit,@p10 bit,@p11 bit,@p12 bit,@p13 bit,@p14 bit,@p15 bit,@p16 bit,@p17 bit,@p18 bit,@p19 varchar(8000),@p20 int,@p21 int,@p22 bit,@RETURN_VALUE int output',@p0=0,@p1=1,@p2=1,@p3=1,@p4=0,@p5=0,@p6=0,@p7=0,@p8=0,@p9=0,@p10=0,@p11=0,@p12=0,@p13=0,@p14=0,@p15=0,@p16=0,@p17=0,@p18=0,@p19=NULL,@p20=0,@p21=10,@p22=0,@RETURN_VALUE=@p26 output
select @p26

.Net C# 程式碼很簡單:

using( BRSDataContext dc = new BRSDataContext() )
{
   dc.TapeInfo_Get(false, false, false, false, false, false, false, false, false, false, false, null, true, null, false, null, null, null, false, query, startRowIndex, count, false)
}

有什麼我想念的嗎?有什麼想法可以如此顯著地影響性能嗎?數據庫 (MSSQL 2008) 和託管執行 LINQ 的 asp.net 站點的網路伺服器位於同一網路上,並且都執行 Windows server 2008 std 32 位。

謝謝您的幫助。

解決方案

SET ARITHABORT ON;

所以這不是 LINQ 問題,而更多的是一般的 SQL Server 問題。

將 arithabort 設置為開啟;只是為了測試它。有幾種推薦的方法來解決這個問題。一種是在儲存過程中添加“with recompile”。但我通常通過不直接使用輸入參數來修復它

前任:

create stored procedure foo( @ParamUserId int)
as
  declare @UserId int
  set @UserId = @ParamUserId

  select * from Users where UserId = @UserId

或類似的東西。

這是一篇關於此事的好文章http://www.simple-talk.com/sql/t-sql-programming/parameter-sniffing/

這是用於設置 arithabort 的 linq 的 C#;

System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(myConnectionString);
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand("set arithabort on;", conn);
command.Connection.Open();
command.ExecuteNonQuery();
CMyDataContext myDataContext = new CMyDataContext(conn);

引用自:https://stackoverflow.com/questions/5553967