如何比较通过LINQ到SQL和普通SQL Server的查询性能

本文关键字:SQL Server 性能 查询 LINQ 何比较 比较 | 更新日期: 2023-09-27 18:19:40

我想比较三种方法的查询执行性能:

  • 对类型化数据集的查询
  • 使用LINQ to SQL进行查询
  • 直接在SQL Server 2008 R2上执行SQL查询

因此,我想运行一些测试szenarios,如下所示:

查询类型化数据集

在这里,我使用数据集设计器创建了数据集。然后我查询相应的TableAdapter,如

var minDat = new DateTime(2014, 5, 1);
var maxDat = new DateTime(2014, 5, 2);
var ta = new MyTableAdapter();
vat res = (from row in ta.GetData() 
              where row.Date >= minDat && row.Date <= maxDat
              select row).ToArray();

这会导致超时,因为它首先从数据库中的表中获取所有数据,并对接收到的对象执行查询。这是意料之中的事。

查询类型化数据集

我在Visual Studio 中使用O/R-Designer创建了一个LINQ到SQL类

var minDat = new DateTime(2014, 5, 1);
var maxDat = new DateTime(2014, 5, 2);
var context = new LtSqlDataContext();
var query = (from row in context.MyTable
                where row.Date >= startTime && row.Date <= endTime
                select row).ToArray;   // I do the .ToArray() to actually receive the whole set of results, i guess here i am doing sth. wrong

这总共需要2294毫秒。到目前为止,这似乎是合理的。

SQL查询

当将LINQ到SQL查询的执行时间与在SQL Server Management Studio中执行的实际SQL查询进行比较时,情况变得越来越奇怪。

declare @min datetime2 = '20140501';
declare @max datetime2 = '20140502';
select * 
    from MyTable 
    where   Date >= @min
        and Date <= @max

这需要6秒多一点的时间,确切地说是6211毫秒(取自SQL Server Profiler-Batch Completed)。

这怎么可能

我想也许我没有正确理解LINQ to SQL的概念。我认为对查询调用ToArray()会导致实际将查询元组转移到数组中。但是,当直接在服务器上执行时,这怎么会比查询快(大约3倍)呢?

有没有更好的方法来比较这两个概念的查询性能?

PS:LINQ to SQL生成的查询与SQL Server Mgmt Studio 中执行的查询相同

编辑:LINQ to SQL生成的查询看起来像下面的

set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language Deutsch
set dateformat dmy
set datefirst 1
set transaction isolation level read committed
exec sp_executesql N'SELECT [t0].[Column1], [t0].[Column2], [t0].[Column3], [t0].[Column4], [t0].[Column5], [t0].[Date], [t0].[Column7]
FROM [Alle].[MyTable] AS [t0]
WHERE ([t0].[Date] >= @p0) AND ([t0].[Date] <= @p1)',N'@p0 datetime2(7),@p1 datetime2(7)',@p0='2014-05-01 00:00:00',@p1='2014-05-02 00:00:00'

我试过在SSMS中执行它,但它仍然需要6秒左右。。。。

如何比较通过LINQ到SQL和普通SQL Server的查询性能

可能是由于非常不同的查询构造,特别是参数化和使用的日期时间类型。你可以在SSMS中比较:

或者你可以在SSMS中做同样的事情,只需:

declare @min datetime = '20140501', @max datetime = '20140502';
exec sp_executesql N'select * 
from MyTable 
where   Date >= @min
and Date <= @max', N'@min datetime, @max datetime', @min, @max;

要在ADO.NET中执行与原始查询相同的测试,您需要一个参数化查询,并将值作为常规DateTime传递,因为这将与其他查询进行很好的比较:

var minDat = new DateTime(2014, 5, 1);
var maxDat = new DateTime(2014, 5, 2);
using(var cmd = conn.CreateCommand()) {
    cmd.CommandText = @"select * 
from MyTable 
where   Date >= @min
    and Date <= @max";
    cmd.Parameters.AddWithValue("min", minDat);
    cmd.Parameters.AddWithValue("max", maxDat);
    using(var reader = cmd.ExecuteReader()) {
        while(reader.Read()) {...}
    }
}

或者更简单地说,使用类似dapper的东西:

var minDat = new DateTime(2014, 5, 1);
var maxDat = new DateTime(2014, 5, 2);
var rows = conn.Query<SomeType>(@"select * 
from MyTable 
where   Date >= @min
    and Date <= @max", new { minDat, maxDat }).ToList();

其中CCD_ 3具有类似于表中的列的属性。

返回了多少行?

565173行返回

给你。SSMS处理许多行的速度较慢。您的基准测试无效。从应用程序中使用ADO.NET执行LINQ查询和SQL查询。遍历所有行。在ADO.NET版本中,检索所有列值以强制反序列化。

也许,随着ADO.NET速度的加快,持续时间现在将非常接近。

如果LINQ到SQL的速度仍然更快,则会出现其他问题,例如缓存计划或SET选项不正确。对于这样一个简单的问题,我会感到惊讶。