【问题标题】:Performance comparison of queries in SQL Server, ADO.NET and LINQ-to-SQLSQL Server、ADO.NET 和 LINQ-to-SQL 中查询的性能比较
【发布时间】:2020-02-04 03:29:41
【问题描述】:

我想知道在 SQL Server 中执行并在 ADO.NET 和 LINQ-to-SQL 中使用的 SQL 查询的性能。

我使用AdventureWorks 数据库和扩展Sales.SalesOrderDetailEnlarged 表,该表有近500 万行。执行查询

select * 
from Sales.SalesOrderDetailEnlarged

在 SQL Server 中持续大约 37 秒,但在 ADO.NET 中执行相同查询大约需要 21 秒。为了测量执行时间,我使用 Stopwatch 和 SQL Server Profiler。

// this is how I perform command execution in ADO.NET
using (SqlConnection sqlConnection = new SqlConnection(GetConnectionString()))
{
    sqlConnection.Open();
    DataSet table = new DataSet();

    using (SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(commandQuery, sqlConnection))
    {
        //stopwatch start
        sqlDataAdapter.Fill(table);
        //stopwatch stop
    }
}

在 Linq-to-SQL 的情况下,我有一个相当于 ADO.NET 中使用的查询的查询。使用 Linq-to-SQL 查询的执行时间大约持续 12-13 秒

var query = from salesOrderDetail in dataContext.SalesOrderDetailEnlargeds
            select salesOrderDetail;

//stopwatch start
query.ToList();
//stopwatch stop

谁能解释一下:

  1. SQL Server 中的查询执行不应该比 ADO.NET 快吗?

  2. 如何比较 ADO.NET 和 Linq-to-SQL 的此查询的执行时间? Linq-to-SQL 实际上是 ADO.NET 之上的一层,那为什么它比 ADO.NET 快(或者我可能尝试用错误的方式衡量它)?

【问题讨论】:

  • 您按什么顺序执行查询?您是否考虑有某种缓存 Sql Server 端?
  • 我以不同的顺序执行查询,但结果仍然相同。我不知道服务器端有任何可用的缓存。
  • 您是说您使用 Profiler 跟踪问题中代码的执行,并看到 Profiler 报告了 37 秒的持续时间而秒表报告了 21 秒?我只看到 SQL 跟踪报告持续时间较短。
  • SSMS 查询显示结果,这需要相当长的时间。其他两个没有。创建数据表也需要时间。换句话说,您正在比较 3 个完全不同的过程。
  • @mikemon,使用 SSMS 运行 SQL 查询不是“在 SQL Server 中”。 SSMS 是一个 ADO.NET 客户端应用程序,与其他任何应用程序一样,Profiler 报告的持续时间将包括应用程序消耗大量结果所需的时间。我认为,如果您在 SSMS 中使用丢弃结果选项运行查询,您会看到与您的 ADO.NET 代码类似的时间,其中不包括在时间上呈现大型结果集。

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


【解决方案1】:

Linq-to-SQL其实是在ADO.NET之上的一层,为什么比ADO.NET快

ADO.NET 有两层。 DataReader 是较低级别,由您的 ADO.NET 代码和 L2S/EF 代码使用。 ADO.NET 中的更高级别是 DataSet/DataTable/DataAdapter,它是一组用于将查询结果加载到内存中的类。 L2S/EF 不使用它。

仅测量查询处理和结果到客户端的传输,.Read() 通过 DataReader 中的行,但不对数据执行任何操作。

例如

int rows = 0;
using (var dr = cmd.ExecuteReader())
{
  while (dr.Read())
  {
    rows+=1;
  }
}

【讨论】:

    【解决方案2】:

    要补充上一个答案,还要记住 Sql server 为查询计划和数据保留缓存。

    当您想比较不同的请求时,您应该在每次测量之前使用以下命令或其他方式清除这些情况(重新启动服务器,使用alter database clear procedure_cache ...见How can I clear the SQL Server query cache?

    DBCC FREEPROCCACHE
    DBCC DROPCLEANBUFFERS
    

    如果您不这样做,第二个措施可能会给出更好但错误的结果,因为数据或计划可能在这些缓存中。

    HTH

    【讨论】:

    • 感谢您的建议! :)
    猜你喜欢
    • 1970-01-01
    • 2013-01-13
    • 2012-05-16
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多