linq vs sql(或.NET app vs SQL Server管理工作室)

时间:2010-12-09 00:57:50

标签: .net sql sql-server linq-to-sql

我有一个linq查询,它根据id列(其中id = @ id)从View中检索行

此查询需要4秒才能运行。我使用SQL Server Profiler来检查linq执行的查询,如果我将该查询直接复制到管理工作室并执行,则查询只需要56ms。

在我的应用程序中,所有linq查询与视图的指数时间增加是一致的。当相同的查询执行时,在我的(WPF)应用程序中可能导致此延长执行时间的原因是什么? 100毫秒?

==编辑==

我设法进一步隔离,评论显示探查器持续时间;

/* 3953ms, 111487 reads */
context.SkuView.Where(p => p.TermId == 35 && !p.IsDeleted).ToList(); 

/* 90ms, 173 reads */
context.SkuView.Where(p => p.TermId == 35).ToList(); 

如果我将(sql呈现的)linq查询直接粘贴到ssms中我得到;

/* 250ms, 173 reads */
SELECT * FROM SkuView WHERE TermId == 35 AND IsDeleted = 0

/* 250ms, 173 reads */
SELECT * FROM SkuView WHERE TermId == 35

因此问题与使用时通过linq读取计数有关!p.IsDeleted ...

4 个答案:

答案 0 :(得分:7)

可能的罪魁祸首是:

  • 争用。从Linq运行时,其他应用程序活动是锁定行,导致查询停止等待锁定。从SSMS运行时,没有其他活动,因此查询结束快。
  • 参数类型的差异。传递NVARCHAR参数以与VARCHAR列进行比较会导致完全扫描(由于Data Type Precedence规则,因此无法使用索引)。这是由错误的LINQ ColumnAttribute引起的。从SSMS运行时,通常会复制查询,并将参数类型更改为VARCHAR。
  • 冷跑与热跑。查询首先由LINq运行,这会使缓存变暖(将数据从磁盘提取到内存)。从SSMS再次运行时,不会等待IO。

在任何情况下,您都可以使用调查工具。

  • 比较两个查询的阅读次数(Profiler中的RPC:CompleteTSQL:BatchComplete事件)
  • 比较计划。使用Showplan XML活动。
  • 查看LINq查询正在做什么sys.dm_exec_requests wait_type,wait_time和wait_resource列
  • 比较两种情况的查询统计信息:sys.dm_exec_query_stats。要查找的内容是logical_reads和physical_reads中两种情况之间的巨大差异,表明计划完全不同(扫描与搜索),或者elapsed_time的差异,但类似的worker_time(表示阻塞,可能发生锁定)。

答案 1 :(得分:2)

更新数据库的统计信息修复了这个问题。

exec sp_updatestats

非常感谢Remus学习;)

答案 2 :(得分:0)

  

此查询需要4秒才能运行...如果我将该查询直接复制到管理工作室并执行,则查询只需要56毫秒。

您的应用程序和管理工作室之间没有神奇的区别。两个程序都创建与数据库的连接并发出sql文本命令(一旦进入数据库服务器:生成查询计划,花费IO和CPU并返回结果)。由于这里唯一的区别是“app建立连接”,你应该检查连接。从连接字符串开始...

假设连接字符串没有问题,请转到SET settings。特别是SET ANSI_NULLS应该打开,因为它可能会干扰带有聚簇索引的计算列和视图。

答案 3 :(得分:0)

默认情况下,

ARITHABORT在SSMS中为ON,默认情况下为SqlClient连接为OFF。

这为我解决了类似的问题:

new SqlCommand("SET ARITHABORT ON", connection).ExecuteNonQuery();