linq vs sql (или .NET приложение против SQL Server Management Studio) - PullRequest
4 голосов
/ 09 декабря 2010

У меня есть запрос linq, который извлекает строки из представления на основе столбца id (где id = @ id)

Этот запрос выполняется 4 секунды.Я использовал SQL Server Profiler для проверки запроса, выполняемого linq, и если я копирую этот запрос непосредственно в Management Studio и выполняю, запрос занимает всего 56 мс.

Это экспоненциальное увеличение времени является одинаковым для всех linqзапросы к просмотрам в моем приложении.Что может быть причиной такого продленного времени выполнения в моем (WPF) приложении, когда одни и те же запросы выполняют <100 мс? </p>

== EDIT ==

Мне удалосьдалее, комментарии показывают продолжительность профилировщика;

/* 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 ]

7 голосов
/ 09 декабря 2010

Возможные виновники:

  • утверждение.При запуске из Linq другие действия приложения блокируют строки и блокируют запрос, ожидая блокировки.При запуске из SSMS другие операции не выполняются, поэтому запрос быстро завершается.
  • Разница в типах параметров.Передача параметра NVARCHAR для сравнения со столбцом VARCHAR приводит к полному сканированию (индекс нельзя использовать из-за правил приоритет типа данных ).Это вызвано неправильным LINQ ColumnAttribute.При запуске из SSMS запрос обычно неправильно копируется, а тип параметра изменяется на VARCHAR.
  • холодный запуск или теплый запуск.Сначала запрос запускается LINq, и это нагревает кэш (извлекает данные с диска в память).При повторном запуске из SSMS ожидание ввода-вывода не ожидается.

В любом случае все инструменты для расследования находятся в вашем распоряжении.

  • сравните количество операций чтения сдва запроса ( RPC: завершено , TSQL: BatchComplete события в Profiler)
  • сравнивают планы.Используйте Событие Showplan XML .
  • посмотрите, что запрос LINq делает : sys.dm_exec_requests столбцы wait_type, wait_time и wait_resource
  • сравнить статистику запросов для двух случаев: sys.dm_exec_query_stats.нужно обратить внимание на большие различия между двумя случаями в логических_текстах и ​​физических_читаниях, указывающие на дико отличающиеся планы (сканирование и поиск) или дикие различия в elapsed_time, но похожие на рабочее-время (указывает на блокировку, вероятны блокировки).
2 голосов
/ 09 декабря 2010

обновление статистики на БД исправило эту проблему.

exec sp_updatestats

Большое спасибо Remus за обучение;)

0 голосов
/ 15 апреля 2013

ARITHABORT по умолчанию включено в SSMS и выключено по умолчанию для соединения SqlClient.

Это решило похожую проблему для меня:

new SqlCommand("SET ARITHABORT ON", connection).ExecuteNonQuery();
0 голосов
/ 09 декабря 2010

Выполнение этого запроса занимает 4 секунды ... если я скопирую этот запрос непосредственно в Management Studio и выполню, запрос займет всего 56 мс.

Нет волшебного различия между вашим приложениеми студия управления.Обе программы создают соединение с базой данных и выдают текстовые команды sql (один раз внутри сервера базы данных: создается план запроса, тратится IO и CPU, а результаты передаются обратно).Поскольку единственным отличием здесь является «приложение, устанавливающее соединение», вы должны проверить соединения.Начните со строк подключения ...

Если в строке подключения нет проблем, перейдите к SET settings .В частности, SET ANSI_NULLS должен быть включен, поскольку он может мешать вычисляемым столбцам и представлениям с кластеризованными индексами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...