为什么在linqtosql中获取空结果集需要这么长时间?

时间:2009-08-10 14:49:40

标签: c# sql-server linq-to-sql

我在我的数据库上运行以下查询,它生成一个sql查询我知道返回0结果,并且在sql management studio中运行需要不到一秒的时间才能返回。

var query = (from item in db.Table
             where item.Field == FieldValue // Field is not the primary key but is indexed
             from other in item.Associated_Table
             select other.Table);
List<Table> result = query.ToList();

Associated_Table是一个连接表,它将Table中的项目与Table中的其他项目相关联。生成的查询如下所示:

declare @p0 as int

SELECT 
   [t2].[ItemCategoryID], 
   [t2].[InventoryItemID], 
   [t2].[SiteID],
   [t2].[ItemDescription], 
   [t2].[AverageMonthlyUsage], 
   [t2].[ReorderLevel], 
   [t2].[ReorderQuantity], 
   [t2].[OtherItemDetails],
   [t2].[Price] AS [IntPrice], 
   [t2].[Ordinal], 
   [t2].[IsBase] AS [IntIsBase], 
   [t2].[Units], 
   [t2].[ProfitCenterID] AS [IntProfitCenterID], 
   [t2].[AccountID], 
   [t2].[PLU] AS [IntPLU], 
   [t2].[BarCode], 
   [t2].[DisplayName], 
   [t2].[ExtraServiceAmount] AS [IntExtraServiceAmount], 
   [t2].[IsSearchable], 
   [t2].[Terminated], 
   [t2].[PdxServiceKey], 
   [t2].[IsOpenPrice], 
   [t2].[ItemPromotionCategoryID]
FROM 
   [dbo].[Inventory.Item] AS [t0]
CROSS JOIN 
   [dbo].[Inventory.ItemExtraAssignment] AS [t1]
INNER JOIN 
   [dbo].[Inventory.Item] AS [t2] 
      ON [t2].[InventoryItemID] = [t1].[ExtraInventoryItemID]
WHERE 
   ([t0].[PLU] = @p0) AND 
   ([t1].[InventoryItemID] = [t0].[InventoryItemID])

在管理工作室中,此查询在一秒钟内运行并返回0结果。为什么执行运行同一查询的2行c#需要2秒钟?我意识到LinqToSql解析对象需要一些开销,但由于没有返回任何对象,所以不应该做任何工作。

我是否缺少一些优化;或者可能需要更改dbml或SQL服务器本身的某些设置?

3 个答案:

答案 0 :(得分:1)

您所描述的行为表明由于过时的统计信息,偏斜的索引或不正确的参数嗅探而导致缓存的查询计划不再适用。

尝试重建相关表格上的索引,或者至少更新统计信息。

[SSMS发出前导,每次强制重新编译]

答案 1 :(得分:1)

Linq必须在运行时翻译表达式树。通常,它会将表达式树转换为查询评估的一部分,但对于许多查询,您可以通过使用CompiledQuery单独进行此操作。

  //do this once
Func<CustomDataContext, int, List<Table>> queryFunc =
System.Data.Linq.CompiledQuery.Compile<CustomDataAccess, int, List<Table>>
( (dc, i) =>
  from item in dc.Table
  where item.Field == i
  from other in item.Associated_Table
  select other.Table).ToList()
);
   //time this
List<Table> result = queryFunc(db, FieldValue);

答案 2 :(得分:0)

第二次运行查询还需要2秒吗? LINQ to SQL可能需要相当长的时间来加载其依赖项并在第一次执行各种初始化时,但之后会很快。

此外,我建议你查看SQL Server日志,看看从LINQ运行时查询在数据库中花了多长时间。