Сравнение производительности запросов в SQL Server, ADO.NET и LINQ-to-SQL - PullRequest
1 голос
/ 06 октября 2019

Меня интересует производительность SQL-запросов, выполняемых в SQL Server и используемых в ADO.NET и LINQ-to-SQL.

Я использую базу данных AdventureWorks с расширенной таблицей Sales.SalesOrderDetailEnlargedкоторый имеет почти 5 миллионов строк. Выполнение запроса

select * 
from Sales.SalesOrderDetailEnlarged

длится около 37 секунд в SQL Server, но выполнение того же запроса в ADO.NET составляет около 21 секунды. Для измерения времени выполнения я использую секундомер и 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 (или, может быть, я пытаюсь измерить его неправильно)?

Ответы [ 2 ]

2 голосов
/ 07 октября 2019

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;
  }
}
0 голосов
/ 07 октября 2019

Чтобы добавить к предыдущему ответу, также имейте в виду, что сервер Sql хранит кэши для планов запросов и данных.

Если вы хотите сравнить разные запросы, перед каждой мерой следует очистить эти случаи с помощью следующегокоманды или другими способами (перезапуск сервера, используя alter database clear_cache ... см. Как очистить кэш запросов SQL Server? )

DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS

Если вы этого не сделаетечто вторая мера может дать гораздо лучшие, но неверные результаты, потому что данные или планы могут находиться в этом кеше.

HTH

...