Generated LinqtoSql Sql 5x slower than SAME EXACT hand-written sql

Posted by JasonM on Stack Overflow See other posts from Stack Overflow or by JasonM
Published on 2010-05-13T14:14:28Z Indexed on 2010/05/15 6:54 UTC
Read the original article Hit count: 264

Filed under:
|
|

I have a sql statement which is hardcoded in an existing VB6 app. I'm upgrading a new version in C# and using Linq To Sql. I was able to get LinqToSql to generate the same sql (before I start refactoring), but for some reason the Sql generated by LinqToSql is 5x slower than the original sql. This is running the generated Sql Directly in LinqPad.

The only real difference my meager sql eyes can spot is the WITH (NOLOCK), which if I add into the LinqToSql generated sql, makes no difference.

Can someone point out what I'm doing wrong here? Thanks!

Existing Hard Coded Sql (5.0 Seconds)

SELECT DISTINCT 
CH.ClaimNum, CH.AcnProvID, CH.AcnPatID, CH.TinNum, CH.Diag1, CH.GroupNum, CH.AllowedTotal  
FROM Claims.dbo.T_ClaimsHeader AS CH WITH (NOLOCK) 
WHERE 
CH.ContractID IN ('123A','123B','123C','123D','123E','123F','123G','123H') 
AND ( ( (CH.Transmited Is Null or CH.Transmited = '') 
AND CH.DateTransmit Is Null 
AND CH.EobDate Is Null 
AND CH.ProcessFlag IN ('Y','E') 
AND CH.DataSource NOT IN ('A','EC','EU') 
AND CH.AllowedTotal > 0 ) ) 
ORDER BY CH.AcnPatID, CH.ClaimNum

Generated Sql from LinqToSql (27.6 Seconds)

-- Region Parameters
DECLARE @p0 NVarChar(4) SET @p0 = '123A'
DECLARE @p1 NVarChar(4) SET @p1 = '123B'
DECLARE @p2 NVarChar(4) SET @p2 = '123C'
DECLARE @p3 NVarChar(4) SET @p3 = '123D'
DECLARE @p4 NVarChar(4) SET @p4 = '123E'
DECLARE @p5 NVarChar(4) SET @p5 = '123F'
DECLARE @p6 NVarChar(4) SET @p6 = '123G'
DECLARE @p7 NVarChar(4) SET @p7 = '123H'
DECLARE @p8 VarChar(1) SET @p8 = ''
DECLARE @p9 NVarChar(1) SET @p9 = 'Y'
DECLARE @p10 NVarChar(1) SET @p10 = 'E'
DECLARE @p11 NVarChar(1) SET @p11 = 'A'
DECLARE @p12 NVarChar(2) SET @p12 = 'EC'
DECLARE @p13 NVarChar(2) SET @p13 = 'EU'
DECLARE @p14 Decimal(5,4) SET @p14 = 0
-- EndRegion
SELECT DISTINCT 
[t0].[ClaimNum], 
[t0].[acnprovid] AS [AcnProvID], 
[t0].[acnpatid] AS [AcnPatID], 
[t0].[tinnum] AS [TinNum], 
[t0].[diag1] AS [Diag1], 
[t0].[GroupNum], 
[t0].[allowedtotal] AS [AllowedTotal]
FROM [Claims].[dbo].[T_ClaimsHeader] AS [t0]
WHERE 
([t0].[contractid] IN (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7)) 
AND (([t0].[Transmited] IS NULL) OR ([t0].[Transmited] = @p8)) 
AND ([t0].[DATETRANSMIT] IS NULL) 
AND ([t0].[EOBDATE] IS NULL) 
AND ([t0].[PROCESSFLAG] IN (@p9, @p10)) 
AND (NOT ([t0].[DataSource] IN (@p11, @p12, @p13))) 
AND ([t0].[allowedtotal] > @p14)
ORDER BY [t0].[acnpatid], [t0].[ClaimNum]

New LinqToSql Code (30+ seconds... Times out )

var contractIds = T_ContractDatas.Where(x => x.EdiSubmissionGroupID == "123-01").Select(x => x.CONTRACTID).ToList();
var processFlags = new List<string> {"Y","E"};
var dataSource = new List<string> {"A","EC","EU"};

var results = (from claims in T_ClaimsHeaders
where contractIds.Contains(claims.contractid)
&& (claims.Transmited == null || claims.Transmited == string.Empty )
&& claims.DATETRANSMIT == null
&& claims.EOBDATE == null
&& processFlags.Contains(claims.PROCESSFLAG)
&& !dataSource.Contains(claims.DataSource)
&& claims.allowedtotal > 0

select new
 {
     ClaimNum = claims.ClaimNum,
     AcnProvID = claims.acnprovid,
     AcnPatID = claims.acnpatid,
     TinNum = claims.tinnum,
     Diag1 = claims.diag1,
     GroupNum = claims.GroupNum,
     AllowedTotal = claims.allowedtotal
 }).OrderBy(x => x.ClaimNum).OrderBy(x => x.AcnPatID).Distinct();

I'm using the list of constants above to make LinqToSql Generate IN ('xxx','xxx',etc) Otherwise it uses subqueries which are just as slow...

© Stack Overflow or respective owner

Related posts about c#

Related posts about linq-to-sql