![](/img/trans.png)
[英]Why is the SQL query from Entity Framework not visible in the Sql Server Profiler when query contains declared variables?
[英]Entity Framework times out but query from profiler executes within milliseconds
以下代碼在60秒后超時。 它應該返回10K行以用於只讀目的:
using (var db = new TUdvEntities(_connectionString))
{
try
{
db.Set<TEjendom>().AsNoTracking();
db.Set<TEjd_ESR>().AsNoTracking();
db.Set<TMat>().AsNoTracking();
IQueryable<TEjendom> query = db.TEjendom;
foreach (var propertyId in propertiesInProgress)
{
query = query.Where(x => x.EjdId != propertyId);
}
var description = propertyState.GetDescription();
var resultListTmp = query.Where(x => x.EjdStatus == description)
.Include(nameof(TEjd_ESR))
.Include(nameof(TMat))
.Take(amount).ToList();
....
}
}
但是,EF生成的查詢(我從SQL Server Profiler中獲取)在一毫秒內執行。
我嘗試使用以下命令禁用更改跟蹤:
db.Configuration.AutoDetectChangesEnabled = false;
但那並沒有幫助。
兩個包含的組合會減慢查詢速度,但是當我刪除其中一個時,它會返回即時結果。
SQL查詢:
exec sp_executesql N'SELECT
[UnionAll1].[EjdId] AS [C1],
[UnionAll1].[EjdId1] AS [C2],
[UnionAll1].[EjdType] AS [C3],
[UnionAll1].[BNummer] AS [C4],
[UnionAll1].[TNummer] AS [C5],
[UnionAll1].[ANummer] AS [C6],
[UnionAll1].[ENummer] AS [C7],
[UnionAll1].[Beskrivelse] AS [C8],
[UnionAll1].[SBT] AS [C9],
[UnionAll1].[EjdStatus] AS [C10],
[UnionAll1].[StatusTimestamp] AS [C11],
[UnionAll1].[IAbo] AS [C12],
[UnionAll1].[AOAttempts] AS [C13],
[UnionAll1].[AboId] AS [C14],
[UnionAll1].[BFE] AS [C15],
[UnionAll1].[UpdateToken] AS [C16],
[UnionAll1].[FEJ] AS [C17],
[UnionAll1].[C1] AS [C18],
[UnionAll1].[ESRId] AS [C19],
[UnionAll1].[EjdId2] AS [C20],
[UnionAll1].[Passiv] AS [C21],
[UnionAll1].[EjdId3] AS [C22],
[UnionAll1].[C2] AS [C23],
[UnionAll1].[C3] AS [C24],
[UnionAll1].[C4] AS [C25],
[UnionAll1].[C5] AS [C26]
FROM (SELECT
CASE WHEN ([Extent2].[ESRId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1],
[Limit1].[EjdId] AS [EjdId],
[Limit1].[EjdId] AS [EjdId1],
[Limit1].[EjdType] AS [EjdType],
[Limit1].[BNummer] AS [BNummer],
[Limit1].[TNummer] AS [TNummer],
[Limit1].[ANummer] AS [ANummer],
[Limit1].[ENummer] AS [ENummer],
[Limit1].[Beskrivelse] AS [Beskrivelse],
[Limit1].[SBT] AS [SBT],
[Limit1].[EjdStatus] AS [EjdStatus],
[Limit1].[StatusTimestamp] AS [StatusTimestamp],
[Limit1].[IAbo] AS [IAbo],
[Limit1].[AOAttempts] AS [AOAttempts],
[Limit1].[AboId] AS [AboId],
[Limit1].[BFE] AS [BFE],
[Limit1].[UpdateToken] AS [UpdateToken],
[Limit1].[FEJ] AS [FEJ],
[Extent2].[ESRId] AS [ESRId],
[Extent2].[EjdId] AS [EjdId2],
[Extent2].[Passiv] AS [Passiv],
[Extent2].[EjdId] AS [EjdId3],
CAST(NULL AS int) AS [C2],
CAST(NULL AS varchar(1)) AS [C3],
CAST(NULL AS varchar(1)) AS [C4],
CAST(NULL AS int) AS [C5]
FROM (SELECT TOP (10416)
[Extent1].[EjdId] AS [EjdId],
[Extent1].[EjdType] AS [EjdType],
[Extent1].[BNummer] AS [BNummer],
[Extent1].[TNummer] AS [TNummer],
[Extent1].[ANummer] AS [ANummer],
[Extent1].[ENummer] AS [ENummer],
[Extent1].[Beskrivelse] AS [Beskrivelse],
[Extent1].[SBT] AS [SBT],
[Extent1].[EjdStatus] AS [EjdStatus],
[Extent1].[StatusTimestamp] AS [StatusTimestamp],
[Extent1].[IAbo] AS [IAbo],
[Extent1].[AOAttempts] AS [AOAttempts],
[Extent1].[AboId] AS [AboId],
[Extent1].[BFE] AS [BFE],
[Extent1].[UpdateToken] AS [UpdateToken],
[Extent1].[FEJ] AS [FEJ]
FROM [dbo].[TEjendom] AS [Extent1]
WHERE ([Extent1].[EjdStatus] = @p__linq__0) OR (([Extent1].[EjdStatus] IS NULL) AND (@p__linq__0 IS NULL)) ) AS [Limit1]
LEFT OUTER JOIN [dbo].[TEjd_ESR] AS [Extent2] ON [Limit1].[EjdId] = [Extent2].[EjdId]
UNION ALL
SELECT
2 AS [C1],
[Limit2].[EjdId] AS [EjdId],
[Limit2].[EjdId] AS [EjdId1],
[Limit2].[EjdType] AS [EjdType],
[Limit2].[BNummer] AS [BNummer],
[Limit2].[TNummer] AS [TNummer],
[Limit2].[ANummer] AS [ANummer],
[Limit2].[ENummer] AS [ENummer],
[Limit2].[Beskrivelse] AS [Beskrivelse],
[Limit2].[SBT] AS [SBT],
[Limit2].[EjdStatus] AS [EjdStatus],
[Limit2].[StatusTimestamp] AS [StatusTimestamp],
[Limit2].[IAbo] AS [IAbo],
[Limit2].[AOAttempts] AS [AOAttempts],
[Limit2].[AboId] AS [AboId],
[Limit2].[BFE] AS [BFE],
[Limit2].[UpdateToken] AS [UpdateToken],
[Limit2].[FEJ] AS [FEJ],
CAST(NULL AS int) AS [C2],
CAST(NULL AS int) AS [C3],
CAST(NULL AS bit) AS [C4],
CAST(NULL AS int) AS [C5],
[Extent4].[EjdId] AS [EjdId2],
[Extent4].[LeKode] AS [LeKode],
[Extent4].[MatNummer] AS [MatNummer],
[Extent4].[EjdId] AS [EjdId3]
FROM (SELECT TOP (10416)
[Extent3].[EjdId] AS [EjdId],
[Extent3].[EjdType] AS [EjdType],
[Extent3].[BNummer] AS [BNummer],
[Extent3].[TNummer] AS [TNummer],
[Extent3].[ANummer] AS [ANummer],
[Extent3].[ENummer] AS [ENummer],
[Extent3].[Beskrivelse] AS [Beskrivelse],
[Extent3].[SBT] AS [SBT],
[Extent3].[EjdStatus] AS [EjdStatus],
[Extent3].[StatusTimestamp] AS [StatusTimestamp],
[Extent3].[IAbo] AS [IAbo],
[Extent3].[AOAttempts] AS [AOAttempts],
[Extent3].[AboId] AS [AboId],
[Extent3].[BFE] AS [BFE],
[Extent3].[UpdateToken] AS [UpdateToken],
[Extent3].[FEJ] AS [FEJ]
FROM [dbo].[TEjendom] AS [Extent3]
WHERE ([Extent3].[EjdStatus] = @p__linq__0) OR (([Extent3].[EjdStatus] IS NULL) AND (@p__linq__0 IS NULL)) ) AS [Limit2]
INNER JOIN [dbo].[TMat] AS [Extent4] ON [Limit2].[EjdId] = [Extent4].[EjdId]) AS [UnionAll1]
ORDER BY [UnionAll1].[EjdId1] ASC, [UnionAll1].[C1] ASC',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'HentData'
有什么建議么?
我同意Allan S. Hansen關於參數嗅探的評論。
您查詢的部分是WHERE ([Extent1].[EjdStatus] = @p__linq__0)
,並且@p__linq__0
參數在結尾的查詢中作為nvarchar(4000)
傳入:
ORDER BY [UnionAll1]。[EjdId1] ASC,[UnionAll1]。[C1] ASC',N'@ p__linq__0 nvarchar(4000) ',@ p__linq__0 = N'HentData'
我猜測EjdStatus列未在數據庫中定義為nvarchar(4000)。 我相信這會使數據庫選擇錯誤的執行計划或索引。 我們遇到了這個問題,我們所做的是確保EF查詢使用了正確的數據類型並且幫助了很多。
我們通過在數據上下文中的OnModelCreating
覆蓋中調用HasDataType
方法來完成此OnModelCreating
:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyClass>().Property(a => a.EjdStatus).HasColumnType("VARCHAR");
//other code here
}
這導致EF在其生成的查詢中使用正確的數據類型,這允許Sql選擇適當的執行計划。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.