Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / ADO.NET-SqlClient-DataReader: Жуткие тормоза / 9 сообщений из 9, страница 1 из 1
22.11.2017, 15:37
    #39557603
Yuri Abele
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ADO.NET-SqlClient-DataReader: Жуткие тормоза
Привет!
Теряюсь даже, как описать.

В общем, есть C# код, который, через SqlClient -овские SqlConnection и SqlCommand вызывает, соответственно, ConnectAsync() и ExecuteReaderAsync() .
Результатов может прийти до нескольких десятков, поэтому после каждого ResultSet-а вызывается reader.NextResultAsync() .
Для каждого ResultSet-а строки данных перебираются в цикле while (await reader.ReadAsync()) {...} .

И получаем жуткие тормоза. Чтобы просто перебрать записи занимает где-то в 10 раз дольше, чем тот же вызов процедуры, но в SSMS (SQL Server Management Studio).
Причем даже в таком варианте, где только перебор:
Код: c#
1.
2.
3.
4.
while (await reader.ReadAsync())
{
    continue;
}



Что мы только не пробовали:
через уже открытое соединение слать сначала T-SQL SET NOCOUNT ON;

добавлять в ConnectionString такой ключ: applicationintent=readonly

играться с SqlConnection.PacketSize

использовать command.ExecuteReaderAsync( CommandBehavior.SequentialAccess )

читать синхронно (вместо while (await reader.ReadAsync()) {...} использовать while (reader.Read()) {...} )

даже так: var table = new DataTable(); table.Load(reader);

Ничего не помогло! Всё таже разница на порядок с SSMS или OSQL.EXE.
Наши JAVA коллеги ржут - переделайте все на JAVA. Блин, но SSMS на том же .NET-е написан, почему такая разница?!
...
Рейтинг: 0 / 0
22.11.2017, 15:56
    #39557620
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ADO.NET-SqlClient-DataReader: Жуткие тормоза
Yuri Abele,

для начала определите, что же медленно забирает или отрабатывает процедура.
...
Рейтинг: 0 / 0
22.11.2017, 16:34
    #39557667
Yuri Abele
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ADO.NET-SqlClient-DataReader: Жуткие тормоза
TaPaKYuri Abele,

для начала определите, что же медленно забирает или отрабатывает процедура.
Я не понял вопроса. На всякий случай (см. выше) - на том же PC, тот же запрос и с того же сервера, но в SSMS всё работает на порядок быстрее
...
Рейтинг: 0 / 0
22.11.2017, 16:38
    #39557672
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ADO.NET-SqlClient-DataReader: Жуткие тормоза
...
Рейтинг: 0 / 0
22.11.2017, 20:08
    #39557843
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ADO.NET-SqlClient-DataReader: Жуткие тормоза
Yuri Abele,

Проблемы с каналом.
...
Рейтинг: 0 / 0
22.11.2017, 20:28
    #39557853
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ADO.NET-SqlClient-DataReader: Жуткие тормоза
Yuri AbeleДля каждого ResultSet-а строки данных перебираются в цикле while (await reader.ReadAsync()) {...} .

И получаем жуткие тормоза. Чтобы просто перебрать записи занимает где-то в 10 раз дольше, чем тот же вызов процедуры, но в SSMS (SQL Server Management Studio).
Причем даже в таком варианте, где только перебор:Только для этой процедуры, или для любой?
Если первое, то причина в разных планах.
...
Рейтинг: 0 / 0
24.11.2017, 10:04
    #39558771
Yuri Abele
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ADO.NET-SqlClient-DataReader: Жуткие тормоза
Ситуация прояснилась.
Оказалось, что дело совсем не .NET-ном куске.

У этой SP, среди прочего, на входе optional параметр @LastSyncDateTime DATE = NULL
Далее в коде:

SET @LastSyncDateTime = ISNULL(@LastSyncDateTime, '1980-01-01');

Ну и два десятка таблиц, фильтрующихся, по этой дате (все переделать на фильтр по LoadID не предлагать - уже занимаются)

Так вот, если вызывать процедуру и явно передать ей дату, даже такую же, как выше, то всё летает.
Если же параметр не указан или ему явно NULL передали, то всё дико тормозит.

Т.е. похоже, что query optimizator выбирает разные планы выполнения в зависимости от значения параметра на входе, а не того значения, которое, потом, в запросе к таблице применится!
Добавить к заголовку процедуры WITH RECOMPILE никаких изменений не породило.

Наш workarround - еще в backend-е смотрим, что там со значением и подменяем пустое на 1980-01-01:

Код: c#
1.
2.
3.
4.
var data = await _syncService.GetClientDataPartial(
	....,
	lastSyncDate: partialParams.LastSyncDate ?? DateTime.ParseExact("1980-01-01", "yyyy-MM-dd", CultureInfo.InvariantCulture),
	....);
...
Рейтинг: 0 / 0
24.11.2017, 11:12
    #39558836
Yuri Abele
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ADO.NET-SqlClient-DataReader: Жуткие тормоза
Корректное решение - не трогать .NET code, а убрать WITH RECOMPILE - нет в нем смысла в нашем случае и добавить где надо:
OPTION (RECOMPILE, USE HINT ('DISABLE_PARAMETER_SNIFFING'))
...
Рейтинг: 0 / 0
24.11.2017, 11:14
    #39558838
Yuri Abele
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ADO.NET-SqlClient-DataReader: Жуткие тормоза
(чтобы все в одном флаконе, так сказать)

Дело в том, что MSSQL query optimizator, действительно, выбирает план на основе исходного значения параметра процедуры, а мы его переписывали. Поэтому см. предыдущий постинг.
...
Рейтинг: 0 / 0
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / ADO.NET-SqlClient-DataReader: Жуткие тормоза / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]