LINQ to SQL比较性能

时间:2010-11-10 11:53:20

标签: c# asp.net sql-server linq-to-sql

我有一个linq to sql查询的问题 - 性能明智。 我想要做的是,找出我的约500项(在列表中)的集合的元素是否匹配数据库条目。目前,仅此操作大约需要300秒才能完成!该数据库包含超过一百万行,并且必将在未来增长,因此这种性能水平如此早就完全是不可接受的。以下示例:

var query = from item in db.DataTable.Where(x => x.date == suppliedDate)
            where inputList.Contains(item.name)
            select new { item.name};

帮助!

编辑: 非常感谢您的所有建议!我只是想添加一些额外的观察,因为我现在能够查看我的LINQ查询的SQL输出(见下文)

SELECT [t0].[name]
FROM [dw].[DataTable] AS [t0]
WHERE ([t0].[name] IN (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17)) AND ([t0].[date] = @p18)
-- @p0: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [Mark]
-- @p1: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [Owen]
-- @p2: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [James]
-- @p3: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [John]

等。

这是否会在数据库上单独点击500次? (正如伊恩建议的那样)?并且有什么方法可以提高性能而不必求助于存储过程或创建额外的表? (这两个选项现在对我来说都不可用)。我已经尝试了Geoff的建议,这使我的运行时间从300秒增加到大约126秒 - 但这仍然很多,特别是考虑到db连接最多只需要不到10秒的时间。

非常感谢

5 个答案:

答案 0 :(得分:2)

可能对使用该查询的数据库发出500个单独的请求!

首先查看在sql server中使用查询分析器运行的sql,看看Linq-to-sql是否正在按预期执行。

答案 1 :(得分:2)

尝试

var query = from item in db.DataTable
            where item.date == suppliedDate
            where inputList.Contains(item.name)
            select new { item.name};

您可以使用LinqPad来测试您的查询,它还会显示生成的SQL。

答案 2 :(得分:2)

-- @p0: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [Mark] 

列varchar?

如果检查该查询的执行计划,您可能会看到sql server将整个索引转换为nvarchar(DOOOOOM!)

修复方法是将参数转换为varchar。


您可以直接获取命令并重置其上的参数类型(在您的情况下为ansi-string)。

http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.getcommand.aspx http://msdn.microsoft.com/en-us/library/system.data.dbtype.aspx

然后你可以在该命令上调用ExecuteReader,产生一个DbDataReader。您可以将此DbDataReader传递给datacontext的Translate方法,它将为您提供linq所期望的IEnumerable<T>

http://msdn.microsoft.com/en-us/library/bb534213.aspx

我已发布完成此操作的代码here

答案 3 :(得分:1)

鉴于您正在处理的记录数量,在数据库中完成此类操作的速度会快得多。

我将列表中的项目批量插入到临时表中,然后根据需要进行内连接或交叉/除外以获得结果。

MSSQL 2008也有一个超快的MERGE sql语句,也可能有所帮助。使用超过十亿条记录执行此类操作需要几毫秒的时间,以便您的硬件能够应对。

这带给我的东西:)硬件。不要估计硬件要求,特别是硬盘驱动器的速度(通常是一个RAID 5/6阵列,包括6/12个主轴之间的任何位置。如果你需要真正良好的性能,你要处理的数据类型< / p>

答案 4 :(得分:1)

更快的方法是避免使用linq代码,可以将inputList名称保存到sql表中(使用xml insert),然后编写执行select的存储过程并返回数据集。然后在linq中你可以调用sp并提取结果。