2011-04-05 17 views
7

Her şey elbette göreli, ancak aynı SQL'i sorgu yöneticisi kullanarak yürütmekle karşılaştırıldığında, büyük bir fark var.Kayıtlı Yordam çağrısı LINQ yavaş

LINQ saklı yordamı çağırdığında, SQL deyimlerinin hangi SQL deyimlerini yürüttüğünü görmek için profiler kullanıyorum. SQL'i kopyalayıp/yapıştırırsam ve aynı SQL'i sorgu yöneticisi aracılığıyla çalıştırırsam, sonuç yaklaşık 1400ms'de döndürülür, sonuç 2 ms içinde döndürülür. Bu, yapmam gereken bir şey olup olmadığını merak ediyor mu? Burada benzer deneyimler var mı?

SQL LINQ göndermek şudur:

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,@[email protected] output 
select @p26 

Net C# kodu basitçe:

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) 
} 

eksik bir şey var mı? Performansı bu kadar çarpıcı bir şekilde etkileyen herhangi bir fikir var mı? Veritabanı (MSSQL 2008) ve LINQ'yi çalıştıran asp.net sitesini barındıran web sunucusu, aynı ağda bulunur ve her ikisi de Windows Server 2008 std 32bit çalıştırır.

Yardımlarınız için teşekkürler.

ÇÖZÜM:

SET ARITHABORT ON; 

Bu yüzden bir LINQ sorun değildi, ama genel bir SQL Server konunun daha fazlası.

+2

İlk önce hangisini yaptınız? SSMS veya uygulama? İki sorgu yöntemi arasında geçiş yaparken tekrar tekrar aynı performans sonuçlarını oluşturabilir misiniz? Tam olarak bahsettiğin ölçüleri nereden aldın? –

+0

@Pete M, yanıtladığınız için teşekkür ederim, önce LINQ ile aradım ve SQL'i Sorgu yöneticisine kopyalayıp çalıştırdım. Ancak sonuç, ilk görüşmeden sonra bile LINQ'den tutarlı şekilde yavaştır. Ölçümler, SQL Server 2008 ile gönderim yapan profilerden geliyor. –

+0

Bummer, bir yürütme planı sorunu olacağını umuyordum ... Sadece açık olmak gerekirse, tamamen SQL Server içinde 1400 ms yürütme süresi görüyor musunuz? Gibi, ulaşım/sunum/diğer dahil değil mi? LINQPad'in var mı? DataContext'inize başvurmayı ve sorguyu uygulamanızın bağlamı dışında çalıştırmayı denerim ve aynı sonuçları alıp alamayacağınızı görürsünüz. Tamamen sunucu tarafında bu çeşit bir farkı görmek ve sürekli olarak birden fazla isabeti görmek, saklı bir prosedürde daha az görmek gerçekten garip ... –

cevap

8

Arithabort'u açık olarak ayarlayın; sadece test etmek içindir. Bu sorunu düzeltmek için önerilen birkaç yol vardır. Bir tanesi saklı yordama "yeniden derleme" eklemektir. Ama genellikle giriş parametrelerini kullanmayarak düzeltmek doğrudan

örn: Böyle

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

    select * from Users where UserId = @UserId 

Ya da bir şey. İşte

madde İşte http://www.simple-talk.com/sql/t-sql-programming/parameter-sniffing/

+0

Çok teşekkürler, çok yardımcı. –

+1

Yardım almaktan memnun oldum. Kafamı tam bir gün boyunca çizmeyi hatırlıyorum. O zaman geri yığın yığını bilmek güzel olurdu :) – ingo

+0

Soruna bazı kapsamlı araştırma için harika bir bağlantı, ama orada ihtiyacınız olan çok şey var A) en az bir saat boyunca okumak ve sindirmek veya B) 15 veya 20 Kaybolacak ve sorununuzu düzeltmenize yardımcı olacak kısmı bulmaya çalışın. İkinci yaklaşım için gittim, ancak sp_recompile çalıştırdıktan sonra bile problem tekrarlandı (yukarıdaki linkin yazarı muhtemel bir durum olacaktır). Benim durumumda, nihayet sorunumu çözdüm, varchar parametreleri için sproc'ma geçtiğim datetime parametrelerini değiştirmekti (ve sonra onları sproc içinde datetime'a dönüştürdüm). – Jagd

2

üzerinde iyi makale linq üzerinde ARITHABORT ayarlama C# olmasıdır;

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); 
İlgili konular