Long running query in EF 5.0 - c#

The following query should return about 7200 records:
using (var context = new RapEntities())
{
context.Configuration.ProxyCreationEnabled = false;
var query = from i in context.QbTxnItems.AsNoTracking()
where (i.ListType == "Invoice")
&& !context.Payments.Any(p => p.QbTxnId == i.QbTxnId && p.QbTxnId != null)
&& !context.QbTxnIgnores.Any(ti => ti.QbTxnId == i.QbTxnId)
orderby i.RefNumber
select i;
var items = RapEntities.GetList(query);
The sql generated (from sql server profiler:
SELECT
[Extent1].[QbTxnItemId] AS [QbTxnItemId],
[Extent1].[ListType] AS [ListType],
[Extent1].[QbTxnId] AS [QbTxnId],
[Extent1].[QbEditSequence] AS [QbEditSequence],
[Extent1].[TxnNumber] AS [TxnNumber],
[Extent1].[RefNumber] AS [RefNumber],
[Extent1].[TxnDate] AS [TxnDate],
[Extent1].[TxnAmt] AS [TxnAmt],
[Extent1].[IsPaid] AS [IsPaid],
[Extent1].[IsCleared] AS [IsCleared],
[Extent1].[LastGetAll] AS [LastGetAll],
[Extent1].[GetIsCleared] AS [GetIsCleared],
[Extent1].[LastModified] AS [LastModified],
[Extent1].[Version] AS [Version],
[Extent1].[RecordStatus] AS [RecordStatus],
[Extent1].[UserId] AS [UserId],
[Extent1].[TableID] AS [TableID]
FROM [dbo].[QbTxnItems] AS [Extent1]
WHERE (N'Invoice' = [Extent1].[ListType]) AND ( NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Payments] AS [Extent2]
WHERE ([Extent2].[QbTxnId] = [Extent1].[QbTxnId]) AND ([Extent2].[QbTxnId] IS NOT NULL)
)) AND ( NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[QbTxnIgnores] AS [Extent3]
WHERE [Extent3].[QbTxnId] = [Extent1].[QbTxnId]
))
ORDER BY [Extent1].[RefNumber] ASC
will not complete in any reasonable amount of time when executed from Entity Framework, but executes instantaneously from SSMS.
Using take(200) to limit the number of rows to 200, the query runs in about 50 msecs even when called from EF. Increasing the number of rows to 500 increases the time to over 5 seconds.
This seems to be inappropriate performance. EF must be capable of returning more than a few hundred rows in a reasonable amount of time. Are there any settings that can be adjusted to increase the capability for running larger queries from EF?

Looks to me like you could speed this up by actually doing some Joins here.
Try this:
var query = (from i in context.QbTxnItems.AsNoTracking()
join p in context.Payments on i.QbTxnId equals p.QbTxnId
join qi in context.QbTxnIgnores on i.QbTxnId equals qi.QbTxnId
where (i.ListType == "Invoice")
select i).OrderBy(i => i.RefNumber);

Related

Linq query taking too long to process results

I have 3 tables
ERPEntry
ERPEntryType
ERPApp
I am trying to get data from these 3 tables using the below queries:.. The table ERPApp is in different context than the other 2 tables, that is the reason i am using 2 queries
var res = (from s in ERPDB.ERPEntrys
join t in ERPDB.ERPEntryTypes
on s.EntryTypeID equals t.EntryTypeID
where s.UserIDAdded == '250176'
select new {s.EntryTypeID, s.DateAdded, t.EntryTypeName, s.AppID }).OrderByDescending(d => d.DateAdded).Take(10).ToArray();
var erpResult = (from a in APPDB.ERPApps.AsEnumerable()
join b in res on a.AppId equals b.AppId
select new ERPInfo
{
EntryId = b.EntryID,
EntryType = b.EntryTypeName,
ERPApp = a.ApplicationName,
DateAdded = b.DateAdded
}).ToList();
I got the desired result but the 2nd query is taking almost 4 minutes to process and return result into varibale erpResult... any help on how can i resolve this performace issue ?
First, the answer:
var res = (from s in ERPDB.ERPEntries
join t in ERPDB.ERPEntryTypes
on s.EntryTypeID equals t.EntryTypeID
where s.UserIdAdded == "250176"
select new { s.EntryID, s.EntryTypeID, s.DateAdded, t.EntryTypeName, s.AppId })
.OrderByDescending(d => d.DateAdded).Take(10).ToArray();
/* Which immediately executes:
exec sp_executesql N'SELECT TOP (10) [t0].[EntryID], [t0].[EntryTypeID],
[t0].[DateAdded], [t1].[EntryTypeName], [t0].[AppId]
FROM [dbo].[ERPEntry] AS [t0]
INNER JOIN [dbo].[ERPEntryType] AS [t1] ON [t0].[EntryTypeID] = [t1].
[EntryTypeID]
WHERE [t0].[UserIdAdded] = #p0
ORDER BY [t0].[DateAdded] DESC',N'#p0 varchar(8000)',#p0='250176'
*/
// Get the distinct AppID values in res
// Executes in memory
var distinctApps = (from r in res select r.AppId).Distinct();
// Query APPDB with the distinct values
var matchingApps = (from a in APPDB.ERPApps where distinctApps
.Contains(a.AppId) select new { a.AppId, a.ApplicationName }).ToArray();
/* Which immediately executes this efficient query:
exec sp_executesql N'SELECT [t0].[AppId], [t0].[ApplicationName]
FROM [dbo].[ERPApp] AS [t0]
WHERE [t0].[AppId] IN (#p0, #p1, #p2, #p3)',N'#p0 bigint,#p1 bigint,#p2
bigint,#p3 bigint',#p0=101,#p1=123,#p2=125,#p3=129
*/
var erpResultWithAppNames = (from a in matchingApps
join b in res on a.AppId equals b.AppId
select new
{
EntryId = b.EntryID,
EntryType = b.EntryTypeName,
ERPApp = a.ApplicationName,
DateAdded = b.DateAdded
}).ToList();
Extra notes:
As already mentioned in the comments, the call to .AsEnumerable() on the APPDB.ERPApps table causes the whole table to be loaded into memory as objects.
Facts:
You had to load 25.000 rows into memory (and convert them to objects),
You are not only loading 25.000 rows. You are loading 25.000 x 173 cells and create 25.000 objects with 173 fields each.
if you could just load the two fields you need (AppId and ApplicationName) instead of all the 173 fields (with whatever data they have) the performance would improve, but would still be inefficient considering what you are trying to achieve.
The current performance problem is in part due to transferring the whole table with all its 173 fields to your server, and in part to mapping all these rows to objects and fields to properties. The impact of each can be measured as further research.
Linq To SQL. When checked with SqlProfiler:
from a in APPDB.ERPApps.AsEnumerable() join b ...
// PROFILED QUERY:
SELECT [t0].[AppId], [t0].[ApplicationName], [t0].[Field1], [t0].[Field2],
[t0].[Field3], [t0].[Field4], [t0].[Field5], [t0].[Field6], [t0].[Field7],
[t0].[Field8], [t0].[Field9], ... ... ... ... [t0].[Field176], [t0].[Field173],
FROM [dbo].[ERPApp] AS [t0]
But:
var erpResult = (from a in APPDB.ERPApps
select new { AppId = a.AppId, ApplicationName = a.ApplicationName }
).ToArray();
// PROFILED QUERY:
SELECT [t0].[AppId], [t0].[ApplicationName]
FROM [dbo].[ERPApp] AS [t0]

Why does adding OrderBy to LINQ to EF query improve its performance?

See the query below. The object and property names have been obfuscated somewhat to not leak confidential/sensitive information, but the query structure is the same.
When the .OrderBy(p => "") is added, which is complete non-sense to me, the query runs much faster. The time it takes to execute the query goes from approx. 2000ms down to approx. 400ms. I have tested it a couple of times, adding and removing only the OrderBy statement.
I am completely puzzled, how can this be? The query is executed on a SQL database in an Azure environment.
I can understand that ordering data on property A, and then selecting records where property A equals some value could potentialy speed up the query. But ordering on an empty string!? What is going on here?
Also I want to note, that the query, without the OrderBy, using Expressions ( as suggested in this post to circumvent SQL parameter sniffing) lowers the execution time also to approx. 400ms. Adding the .OrderBy(p => "") then doesn't make any noticeable difference.
var query = (from p in Context.Punders.Where(p => p.A == A)
.Where(p => null != p.SomeNumber)
.Where(p => p.StatusCode == Default ||
p.StatusCode == Cancelled)
.Where(p => p.DatePosted >= startDate && p.DatePosted <= endDate)
join f in Context.Founders.Where(f => f.A == A) on p.Code equals f.Code
join r in Context.Rounders.Where(r => r.A == A) on p.Code equals r.Code
into rg
from r in rg.DefaultIfEmpty()
join pt in Context.FishTypes.Where(ft => ft.A ==A) on p.Code equals pt.Code
where r == null
select new
{
p.Code,
f.B,
f.C,
p.D,
p.E,
pt.F,
pt.G,
p.H
})
.OrderBy(p => "");
Query without the .OrderBy(...
SELECT [Filter1].[q] AS [q],
[Filter1].[c1] AS [edoc],
[Filter1].[oc1] AS [wnrdc],
[Filter1].[otc1] AS [weener],
[Filter1].[ptc1] AS [pmtpdc],
[Extent4].[isr] AS [isr],
[Extent4].[rac] AS [rac],
[Filter1].[arn] AS [arn]
FROM (SELECT [Extent1].[pcid] AS [pcid1],
[Extent1].[edoc] AS [c1],
[Extent1].[pmtpdc] AS [ptc1],
[Extent1].[q] AS [q],
[Extent1].[arn] AS [arn],
[Extent1].[dateposted] AS [DatePosted],
[Extent2].[pcid] AS [pcid2],
[Extent2].[wnrdc] AS [oc1],
[Extent2].[weener] AS [otc1]
FROM [fnish].[post] AS [Extent1]
INNER JOIN [fnish].[olik] AS [Extent2]
ON [Extent1].[olikedoc] = [Extent2].[edoc]
LEFT OUTER JOIN [fnish].[receivable] AS [Extent3]
ON ( [Extent3].[pcid] = #p__linq__4 )
AND ( [Extent1].[edoc] =
[Extent3].[pepstedoc] )
WHERE ( [Extent1].[arn] IS NOT NULL )
AND ( [Extent1].[posttedoc] IN ( N'D', N'X' ) )
AND ( [Extent3].[id] IS NULL )) AS [Filter1]
INNER JOIN [fnish].[paymenttype] AS [Extent4]
ON [Filter1].[ptc1] = [Extent4].[edoc]
WHERE ( [Filter1].[pcid1] = #p__linq__0 )
AND ( [Filter1].[dateposted] >= #p__linq__1 )
AND ( [Filter1].[dateposted] <= #p__linq__2 )
AND ( [Filter1].[pcid2] = #p__linq__3 )
AND ( [Extent4].[pcid] = #p__linq__5 )
Query with the .OrderBy(...
SELECT [Project1].[q] AS [q],
[Project1].[edoc] AS [edoc],
[Project1].[wnrdc] AS [wnrdc],
[Project1].[weener] AS [weener],
[Project1].[pmtpdc] AS [pmtpdc],
[Project1].[isr] AS [isr],
[Project1].[rac] AS [rac],
[Project1].[arn] AS [arn]
FROM (SELECT N'' AS [C1],
[Filter1].[c1] AS [edoc],
[Filter1].[ptc1] AS [pmtpdc],
[Filter1].[q] AS [q],
[Filter1].[arn] AS [arn],
[Filter1].[oc1] AS [wnrdc],
[Filter1].[otc1] AS [weener],
[Extent4].[isr] AS [isr],
[Extent4].[rac] AS [rac]
FROM (SELECT [Extent1].[pcid] AS [pcid1],
[Extent1].[edoc] AS [c1],
[Extent1].[pmtpdc] AS [ptc1],
[Extent1].[q] AS [q],
[Extent1].[arn] AS [arn],
[Extent1].[dateposted] AS [DatePosted],
[Extent2].[pcid] AS [pcid2],
[Extent2].[wnrdc] AS [oc1],
[Extent2].[weener] AS [otc1]
FROM [fnish].[post] AS [Extent1]
INNER JOIN [fnish].[olik] AS [Extent2]
ON [Extent1].[olikedoc] = [Extent2].[edoc]
LEFT OUTER JOIN [fnish].[receivable] AS [Extent3]
ON ( [Extent3].[pcid] =
#p__linq__4 )
AND ( [Extent1].[edoc] =
[Extent3].[pepstedoc] )
WHERE ( [Extent1].[arn] IS NOT NULL )
AND ( [Extent1].[posttedoc] IN ( N'D', N'X' ) )
AND ( [Extent3].[id] IS NULL )) AS [Filter1]
INNER JOIN [fnish].[paymenttype] AS [Extent4]
ON [Filter1].[ptc1] = [Extent4].[edoc]
WHERE ( [Filter1].[pcid1] = #p__linq__0 )
AND ( [Filter1].[dateposted] >= #p__linq__1 )
AND ( [Filter1].[dateposted] <= #p__linq__2 )
AND ( [Filter1].[pcid2] = #p__linq__3 )
AND ( [Extent4].[pcid] = #p__linq__5 )) AS [Project1]
ORDER BY [Project1].[c1] ASC
Conclusion
From what I have learned, with a bit of a guess: It is case specific behavior. In my case, the performance gain is likely due to a different execution plan being constructed by the SQL server that is yielding a better performing query. I've seen a different execution plan with the query without the OrderBy using the SQL statement OPTION(RECOMIPILE) that showed similar performance gain. So adding the OrderBy to the LINQ query is very likely (I think) producing a different execution plan that yields a better performing query.
Given your note
Also I want to note, that the query, without the OrderBy, using
Expressions ( as suggested in this post to circumvent SQL parameter
sniffing) lowers the execution time also to approx. 400ms. Adding the
.OrderBy(p => "") then doesn't make any noticeable difference.
The most reasonable explanation is: OrderBy has the same effect as using explicit values instead of parameters. So if you had pre-cached plan for given query, and with particular parameter values this plan is not optimal (2 seconds) - changing this query by adding useless OrderBy to it will force SQL Server to create new execution plan for this query, and so will negate effect of old non-optimal execution plan. Of course, it should be clear that this is not a good way to negate plan caching.

Why are multiple where in LINQ so slow?

Using C# and Linq to SQL, I found that my query with multiple where is orders of magnitude slower than with a single where / and.
Here is the query
using (TeradiodeDataContext dc = new TeradiodeDataContext())
{
var filterPartNumberID = 71;
var diodeIDsInBlades = (from bd in dc.BladeDiodes
select bd.DiodeID.Value).Distinct();
var diodesWithTestData = (from t in dc.Tests
join tt in dc.TestTypes on t.TestTypeID equals tt.ID
where tt.DevicePartNumberID == filterPartNumberID
select t.DeviceID.Value).Distinct();
var result = (from d in dc.Diodes
where d.DevicePartNumberID == filterPartNumberID
where diodesWithTestData.Contains(d.ID)
where !diodeIDsInBlades.Contains(d.ID)
orderby d.Name
select d);
var list = result.ToList();
// ~15 seconds
}
However, when the condition in the final query is this
where d.DevicePartNumberID == filterPartNumberID
& diodesWithTestData.Contains(d.ID)
& !diodeIDsInBlades.Contains(d.ID)
// milliseconds
it is very fast.
Comparing the SQL in result before calling ToList(), here are the queries (value 71 manually added in place of #params)
-- MULTIPLE WHERE
SELECT [t0].[ID], [t0].[Name], [t0].[M2MID], [t0].[DevicePartNumberID], [t0].[Comments], [t0].[Hold]
FROM [dbo].[Diode] AS [t0]
WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM (
SELECT DISTINCT [t2].[value]
FROM (
SELECT [t1].[DiodeID] AS [value]
FROM [dbo].[BladeDiode] AS [t1]
) AS [t2]
) AS [t3]
WHERE [t3].[value] = [t0].[ID]
))) AND (EXISTS(
SELECT NULL AS [EMPTY]
FROM (
SELECT DISTINCT [t6].[value]
FROM (
SELECT [t4].[DeviceID] AS [value], [t5].[DevicePartNumberID]
FROM [dbo].[Test] AS [t4]
INNER JOIN [dbo].[TestType] AS [t5] ON [t4].[TestTypeID] = ([t5].[ID])
) AS [t6]
WHERE [t6].[DevicePartNumberID] = (71)
) AS [t7]
WHERE [t7].[value] = [t0].[ID]
)) AND ([t0].[DevicePartNumberID] = 71)
ORDER BY [t0].[Name]
and
-- SINGLE WHERE
SELECT [t0].[ID], [t0].[Name], [t0].[M2MID], [t0].[DevicePartNumberID], [t0].[Comments], [t0].[Hold]
FROM [dbo].[Diode] AS [t0]
WHERE ([t0].[DevicePartNumberID] = 71) AND (EXISTS(
SELECT NULL AS [EMPTY]
FROM (
SELECT DISTINCT [t3].[value]
FROM (
SELECT [t1].[DeviceID] AS [value], [t2].[DevicePartNumberID]
FROM [dbo].[Test] AS [t1]
INNER JOIN [dbo].[TestType] AS [t2] ON [t1].[TestTypeID] = ([t2].[ID])
) AS [t3]
WHERE [t3].[DevicePartNumberID] = (71)
) AS [t4]
WHERE [t4].[value] = [t0].[ID]
)) AND (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM (
SELECT DISTINCT [t6].[value]
FROM (
SELECT [t5].[DiodeID] AS [value]
FROM [dbo].[BladeDiode] AS [t5]
) AS [t6]
) AS [t7]
WHERE [t7].[value] = [t0].[ID]
)))
ORDER BY [t0].[Name]
The two SQL queries execute in < 1 second in SSMS and produce the same results.
So I'm wondering why the first is slower on the LINQ side. It's worrying to me because I know I've used multiple where elsewhere, without being aware of a such a severe performance impact.
This question even has answered with both multiple & and where. And this answer even suggests using multiple where clauses.
Can anyone explain why this happens in my case?
Because writing like this
if (someParam1 != 0)
{
myQuery = myQuery.Where(q => q.SomeField1 == someParam1)
}
if (someParam2 != 0)
{
myQuery = myQuery.Where(q => q.SomeField2 == someParam2)
}
is NOT(upd) the same as (in case when someParam1 and someParam2 != 0)
myQuery = from t in Table
where t.SomeField1 == someParam1
&& t.SomeField2 == someParam2
select t;
is (NOT deleted) the same as
myQuery = from t in Table
where t.SomeField1 == someParam1
where t.SomeField2 == someParam2
select t;
UPD
Yes, I do mistake. Second query is same, first is not same.
First and Second queries not EXACTLY the same. Let me show you what I mean.
1st query with lamda-expression writen as
t.Where(r => t.SomeField1 == someParam1 && t.SomeField2 == someParam2)
2nd query as
t.Where(r => r.SomeField1 == someParam1).Where(r => r.SomeField2 == someParam2)
In this case in generated SQL Predicate with SomeField2 goes first (it is important, see below)
In 1st case we getting this SQL:
SELECT <all field from Table>
FROM table t
WHERE t.SomeField1 = :someParam1
AND t.SomeField2 = :someParam2
In 2 case the SQL is:
SELECT <all field from Table>
FROM table t
WHERE t.SomeField2 = :someParam2
AND t.SomeField1 = :someParam1
As we see there are 2 'same' SQLs. As we see, the OP's SQLs are also 'same', they are different in order of predicates in WHERE clause (as in my example). And I guess that SQL optimizer generate 2 different execution plans and may be(!!!) doing NOT EXISTS, then EXISTS and then filtering take more time than do first filtering and after that do EXISTS and NOT EXISTS
UPD2
It is a 'problem' of Linq Provider (ORM). I'm using another ORM (linq2db), and it generates for me EXACTLY the same SQLs in both cases.

Linq slow while SQL fast

When I'm trying the next linq query, it is slow (1.5 s):
var rslt = (from t in context.Set<SUB_Transactions>()
where
t.UpdateDate > query.LastUpdate &&
t.TransactionID > query.Index
select new
{
TransactionID = t.TransactionID
}).OrderBy(t => t.TransactionID).Take(query.Amount).ToList();
When converted to SQL, this query is super fast (40 ms):
SELECT TOP (300)
[Project1].[TransactionID] AS [TransactionID]
FROM ( SELECT
[Extent1].[TransactionID] AS [TransactionID]
FROM [dbo].[SUB_Transactions] AS [Extent1]
WHERE ([Extent1].[UpdateDate] > #p__linq__0) AND ([Extent1].[TransactionID] > #p__linq__1)
) AS [Project1]
ORDER BY [Project1].[TransactionID] ASC
What is going on here?
Removing the Take in the first query gives a fast result as well (given the fast that there are no new transactions)
There is a composite index on TransactionID and UpdateDate.
As far as your example goes, this could make your query faster but without some sample data it's not possible to test from our end:
var rslt = (from t in context.Set<SUB_Transactions>()
where t.TransactionID > query.Index // invert order of filter
&& t.UpdateDate > query.LastUpdate
order by t.TransactionID // you can orderby here
select t.TransactionID) // remove anonymous object
.Take(query.Amount)
.AsNoTracking() // you won't be changing IDs so no need to track them
.ToList();
You might also gain some performance if you used the DbSet<SUB_Transactions> instead of calling Set<SUB_Transactions>() which needs to locate the DbSet in the DbContext

Linq to SQL: Query runs fine in SQL Server Management Studio, but times out on the application

I'm maintaining the code of a legacy application. It is using Entity Framework 3.5 and updating it to a newer version at the moment is not possible.
There is a query that lately has started to time out. This is the query in LINQ:
var compoQueryResult = (from composition in MyAppDataContext.Compositions
join compositionStatus in MyAppDataContext.CompositionStatus on composition.StatusID equals compositionStatus.CompositionStatusID
join compoUnit in MyAppDataContext.CompositionUnits on composition.CompositionID equals compoUnit.CompositionID
join unit in MyAppDataContext.Units on compoUnit.UnitID equals unit.UnitID
join carUnit in MyAppDataContext.Car_Units on unit.UnitID equals carUnit.UnitId
join car in MyAppDataContext.Cars on carUnit.CarId equals car.CarID
join location in MyAppDataContext.Locations on unit.ParkedLocationID equals location.LocationID
from road in MyAppDataContext.Roads.Where(r => r.RoadID == unit.RoadID).DefaultIfEmpty()
from ta in MyAppDataContext.Allocations.Where(ta => ta.CompositionId == composition.CompositionID).DefaultIfEmpty()
from arrivalLocation in MyAppDataContext.Locations.Where(al => al.LocationID == ta.EndLocationID).DefaultIfEmpty()
where (MyApp.IsAdministrator || MyApp.GetLineIds().Contains(car.LineId.Value))
&& car.LineId.Value == LineId
&& (statusId == null || statusId == compositionStatus.CompositionStatusID)
&& (locationId == null || unit.ParkedLocationID == locationId)
&& (!onlyATMS.HasValue
|| (onlyATMS == true && composition.CompositionName.Contains(Common.Constants.ATMSSymbol))
|| (onlyATMS == false && !composition.CompositionName.Contains(Common.Constants.ATMSSymbol)))
select new CompositionQueryResultItem
{
CompositionId = composition.CompositionID,
CompositionName = composition.CompositionName,
CompositionNumber = composition.CompositionNumber,
DateTimeModified = composition.DataModified,
Status = compositionStatus.CompositionStatusDesc,
Location = location.LocationName,
Road = road.Name,
Number = ta.Number,
DepartureTime = ta.DepartTime,
ArrivalLocation = arrivalLocation.LocationName,
ArrivalTime = ta.ArriveTime
}).Distinct().ToList();
After debugging the app I can see that the following query is being executed:
SELECT DISTINCT [t10].[CompositionID] AS [CompositionId], [t10].[CompositionName], [t10].[CompositionNumber], [t10].[value] AS [DateTimeModified], [t10].[CompositionStatusDesc] AS [Status], [t10].[LocationName] AS [Location], [t10].[value2] AS [Road], [t10].[value3] AS [Number], [t10].[value4] AS [DepartureTime], [t10].[value5] AS [ArrivalLocation], [t10].[value6] AS [ArrivalTime]
FROM (
SELECT [t0].[CompositionID], [t0].[CompositionName], [t0].[CompositionNumber], [t0].[DataModified] AS [value], [t1].[CompositionStatusDesc], [t6].[LocationName], [t7].[Name] AS [value2], [t8].[Number] AS [value3], [t8].[DepartTime] AS [value4], [t9].[LocationName] AS [value5], [t8].[ArriveTime] AS [value6], [t5].[LineId]
FROM [dbo].[Composition] AS [t0]
INNER JOIN [dbo].[CompositionStatus] AS [t1] ON [t0].[StatusID] = [t1].[CompositionStatusID]
INNER JOIN [dbo].[CompositionUnit] AS [t2] ON [t0].[CompositionID] = [t2].[CompositionID]
INNER JOIN [dbo].[Unit] AS [t3] ON [t2].[UnitID] = [t3].[UnitID]
INNER JOIN [dbo].[Car_Unit] AS [t4] ON [t3].[UnitID] = [t4].[UnitId]
INNER JOIN [dbo].[Car] AS [t5] ON [t4].[CarId] = [t5].[CarID]
INNER JOIN [dbo].[Location] AS [t6] ON [t3].[ParkedLocationID] = ([t6].[LocationID])
LEFT OUTER JOIN [dbo].[Road] AS [t7] ON ([t7].[RoadID]) = [t3].[RoadID]
LEFT OUTER JOIN [dbo].[Allocation] AS [t8] ON [t8].[CompositionId] = ([t0].[CompositionID])
LEFT OUTER JOIN [dbo].[Location] AS [t9] ON [t9].[LocationID] = [t8].[EndLocationID]
) AS [t10]
WHERE ([t10].[LineId]) = #p0
If I execute that query on SQL Server Manager Studio I get no issues at all. It executes in less than one second. However, the application is timing out and I have no idea why.
I tried doing
MyAppDataContext.ObjectTrackingEnabled = false;
but I still get the same error.
I'm about to give up and create an stored procedure instead, but I can't grasp why the timeout is happening.
The query execution plan that is being used by the SQL Server can be different when the same query is run through the application. Check your execution plans. You can use hints like option(recompile) at the end of the query or you can optimize it for a particular Lineid if for different id's the rows returned are significantly different.
Sometimes, using such hints make it slow in SSMS but not in application. You can find a solution after some hit and trial.

Categories