|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Привет всем! Сложилась забавная ситуация. При вызове запроса из ASP.NET Web Service метода - запрос выполняется 30 секунд (по статистике профайлера). Снимаю текст вызова в SQL Server Profiler. Выполняю его же из SQL Server Management Studio. Время выполнения меньше секунды. При повторном выполнении операции - та же картина. Из сервиса - 30 секунд, из студии - меньше секунды. Не представляю с какой стороны подобраться к решению проблемы. Может кто-то подсказать? К сообщению приложено два скрина из профайлера Скрин 1 - 30 секунд Скрин 2 - меньше секунды ... |
|||
:
Нравится:
Не нравится:
|
|||
30.10.2017, 18:46 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
... |
|||
:
Нравится:
Не нравится:
|
|||
30.10.2017, 18:53 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Shocker.Pro http://www.somewheresomehow.ru/fast-in-ssms-slow-in-app-part1/ В моем случае авторSET ARITHABORT OFF; не привел к замедлению выполнения запроса в SSMS. Вобщем, первая часть не помогла - попробую покурить остальные. Но - спасибо за помощь ... |
|||
:
Нравится:
Не нравится:
|
|||
30.10.2017, 20:33 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Чуть больше подробностей. Хранимая процедура содержит большой запрос, пересекающий десятка полтора таблиц. При этом ожидается, что в результате будет не более 3-4 строк. Параметр процедуры - ИД записи в одной из таблиц. Решил протестировать таким образом. Сократил запрос до обращения к ОДНОЙ таблице, по ключу которой и идет поиск. И... Все равно 30 секунд. Выполнил следующее: Код: sql 1.
и затем по совету автора статьи - запрос, возвращающий новый план из кеша Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45.
И вот - смотрю я в сгенерированный план... А там - Clustered Index Seek, при этом верно определяется Estimated Number of Rows - 1. И при этом - при выполнении из приложения - зачем-то все это длится около 30 секунд... ... |
|||
:
Нравится:
Не нравится:
|
|||
30.10.2017, 21:04 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Vadim Romanenko, в студии пробовали выполнять именно через exec sp_executesql ? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.10.2017, 22:02 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
skyANAVadim Romanenko, в студии пробовали выполнять именно через exec sp_executesql ? Проблема не на моем тестовом сервере. Самая печаль в том, что перенес базу локально к себе - проблема не повторяется ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 14:09 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Может надо обновить статистику на таблице? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 14:27 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Shocker.Pro, обновлял - еще вчера. Но не удивлюсь если поможет экспорт-импорт. Но на промбазе это делать не очень хорошо. Там и база под 60 гиг... Ну и хотелось бы понять в чем проблема и как ее решить кроме как экспортом-импортом. ПС: пользовался вот этим ресурсом для получения скрипта сбора статистики тынц ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 14:36 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Shocker.ProМожет надо обновить статистику на таблице? С другой стороны - может поделитесь Вашим скриптом по сбору статистики и обновлению индексов? Возможно, мой подход не торт ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 14:52 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Забавно, но экспорт-импорт в новую БД на проблемном сервере не привел к решению проблемы. Т.е. с импортированной копией БД и перенастроенным сервисом - та же проблема с производительностью. Вот тут я уже совсем в шоке ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 14:56 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
А нет, все на месте. Сейчас буду дальше тестировать. Не обновил все окружение, потому не шел на самом деле вызов... Пардоньте. буду экспериментировать ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 15:07 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Как насчет WITH (NOLOCK)? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 15:10 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Shocker.ProКак насчет WITH (NOLOCK)? В случае, когда я экспериментирую с копией БД на моем рабочем ПК - доступ к восстановленной БД имею только я. Параллельные записи исключены. И соответственно блокировки со стороны других сессий. Потому, видимо, этот параметр ни при чем. Или я неверно понимаю для чего этот параметр нужен? ПС: в запросе этого параметра нет ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 15:17 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Итак, все-таки разобрался, что в восстановленной БД проблема осталась и это радует. Предыдущие дергания попросил прибить модератора - извиняюсь за искривление описания задачи. Сейчас попробую подключиться из студии и выполнить тот же самый запрос ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 15:18 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Vadim RomanenkoИли я неверно понимаю для чего этот параметр нужен?Дело не в сторонних блокировках, а в том, что сам запрос будет ставить блокировки на страницы, которые читает. А вообще, обсуждать оптимизацию запроса в ASP вместо MSSQL наверное не очень логично, может стоить завести там новую тему, очистив ее от шелухи. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 16:56 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Shocker.ProVadim RomanenkoИли я неверно понимаю для чего этот параметр нужен?Дело не в сторонних блокировках, а в том, что сам запрос будет ставить блокировки на страницы, которые читает. Если Вы предлагаете использовать этот хинт - то в моем случае это, мне кажется, бессмысленно. Потому что при тестировании сторонних блокировок быть не может. Если предполагаете что этот хинт уже стоит и он вносит сумятицу - то нет, не стоит. Shocker.ProА вообще, обсуждать оптимизацию запроса в ASP вместо MSSQL наверное не очень логично, может стоить завести там новую тему, очистив ее от шелухи. Так проблема в том, что чисто сама процедура выполняется мгновенно :) Проблема именно при вызове из приложения... Я не вполне понимаю что тут можно оптимизировать... Разве что попробовать вручную как-то хинтами зафиксировать план... ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 17:15 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
skyANAVadim Romanenko, в студии пробовали выполнять именно через exec sp_executesql ? Наконец-то попробовал. Из студии запрос отрабатывает мгновенно. Проблем нет. При вызове из приложения - 30 секунд... ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 17:16 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Единственная разница, которая мне видна - это в профайлере в колонке Event Class - при медленном выполнении указано RPC:Completed, при быстром - SQL:BatchCompleted. Что-то мне подсказывает, что где-то здесь и порылась собака. Кто может подсказать - может мне как-то переписать вызов? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 17:18 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Собственно, сейчас работа идет через OleDb (OleDbCommand) ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 17:23 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Vadim RomanenkoТак проблема в том, что чисто сама процедура выполняется мгновенно :) Проблема именно при вызове из приложения...Тем не менее, люди там в курсе, что у многих возникает проблема другого плана при вызове из приложения (и в курсе той статьи, которую я привел в начале) и они смогут дать совет, куда и как копать. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 17:39 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Shocker.ProVadim RomanenkoТак проблема в том, что чисто сама процедура выполняется мгновенно :) Проблема именно при вызове из приложения...Тем не менее, люди там в курсе, что у многих возникает проблема другого плана при вызове из приложения (и в курсе той статьи, которую я привел в начале) и они смогут дать совет, куда и как копать. Ок, спасибо, попробую создать аналогичную тему в ветке про SQL Server. ПС: попробовал через профайлер сравнить планы - навскидку они одинаковые :( Это была моя последняя версия... ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 17:57 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Vadim RomanenkoЕсли Вы предлагаете использовать этот хинт - то в моем случае это, мне кажется, бессмысленно. Потому что при тестировании сторонних блокировок быть не может. Ну да, конечно не может быть. А на деле: 20917539 ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 09:16 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
skyANAVadim RomanenkoЕсли Вы предлагаете использовать этот хинт - то в моем случае это, мне кажется, бессмысленно. Потому что при тестировании сторонних блокировок быть не может. Ну да, конечно не может быть. А на деле: 20917539 Да-да, я был неправ :) Похоже, причина столь странного поведения найдена. Хотя я так и не понимаю до сих пор - каким образом сервис таки получает данные ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 14:08 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Vadim RomanenkoХотя я так и не понимаю до сих пор - каким образом сервис таки получает данныеНу если Вы (его аффтар. Эдакий машинист-многостаночник. Имеющий сырцы абсолютно всех компонентов. И допиливающий тоже все компоненты. И клиент-серверное приложение, и sql-серверную часть, и web services) не понимаете, то скорее всего это... Мистика! ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 18:31 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Так и запишем - мистика :) ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 19:21 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Vadim RomanenkoСобственно, сейчас работа идет через OleDb (OleDbCommand) У Вас в try что записано? Прямо копи-пастом из msdn? // Start a local transaction with ReadCommitted isolation level. transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted); В случае срыва через 30 секунд блокировки Вы что делаете в catch (Exception ex)? Выложите свой код на C#! ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 19:37 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Andy_OLAP, не все так просто. Но основные моменты попробую осветить Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51.
где BuildParameters - просто формирует набор OleDbParameter ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 19:42 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Ах, да, про try Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34.
Хотя, скорее всего, это уже лишнее. Отмечу только, что responce не содержит сообщения об ошибке. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 19:45 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Vadim Romanenko, "DBUtils.ExecSQL" - это что за ерунда такая? DBUtils - это же JDBC, откуда он в C#? Внутренний компонент как черный ящик с передачей параметров conn as OleDbConnection, null, "exec sq_WSGetAppByLegId ?", new object[] { legId }), а внутри try и catch как угодно написаны? Что за второй параметр, почему null? В компоненте не настраивается уровень изоляции для Connection? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 19:48 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Andy_OLAP, Понял. Это идет вызов вот отсюда. OleDbTransaction как null. public static OleDbDataReader ExecSQL(OleDbConnection conn, OleDbTransaction trans, string sql, object[] parameters) { OleDbCommand oleCmd = new OleDbCommand(sql); oleCmd.CommandTimeout = 300; oleCmd.Connection = conn; BuildParameters(oleCmd, parameters); if (conn.State == ConnectionState.Closed) conn.Open(); if (trans != null) oleCmd.Transaction = trans; return oleCmd.ExecuteReader(CommandBehavior.Default); } Сейчас разберемся дальше, что делать. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 19:52 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Andy_OLAP, это самописная утилита. Метод которой на вход получает несколько параметров: - connection - transaction (can be null) - маску вызова (из серии "exec some_sp ?, ?") - массив значений параметров хранимой процедуры В данном случае объект транзакции пустой. Подключение к БД устанавливается на основе connection string. Из "подозрительного" там имеются следующие параметры: - Persist Security Info=False; - multipleactiveresultsets=True; - Enlist=false; Все остальное - я вроде бы привел ПС: совпадение названия утилиты с какими-то существующими "в стороне" - исключительно случайное :) ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 19:54 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Andy_OLAP, Мой главный вопрос - есть ли возможность создать честный параллельный thread, в который я бы перенес код обработки. При этом чтобы метод веб сервиса вернул управление вызвавшей его хранимой процедуре. Самый логичный способ решения этой проблемы, на самом деле - был подсказан уже кем-то. Это сделать нотификацию на клиенте. После явного коммита в том самом клиенте. Но этот способ очень не хочется осуществлять - в связи с необходимостью провести обновление клиентского приложения у всех заказчиков. Основная проблема в административных трудностях. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 19:57 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Andy_OLAPAndy_OLAP, Понял. Это идет вызов вот отсюда. OleDbTransaction как null. public static OleDbDataReader ExecSQL(OleDbConnection conn, OleDbTransaction trans, string sql, object[] parameters) { OleDbCommand oleCmd = new OleDbCommand(sql); oleCmd.CommandTimeout = 300; oleCmd.Connection = conn; BuildParameters(oleCmd, parameters); if (conn.State == ConnectionState.Closed) conn.Open(); if (trans != null) oleCmd.Transaction = trans; return oleCmd.ExecuteReader(CommandBehavior.Default); } Сейчас разберемся дальше, что делать. Идет вызовconn.Open(); Далее сразу на oleCmd выполняется ExecuteReader. А нужно вставить далее например что-то типа oleCmd.Transaction = onn.BeginTransaction(level, "DirtyReadFirst"). Не силен в C#, попросите коллег подсказать, как задавать уровни изоляции (а точнее режим блокировки транзакций для подключения) помимо дефолтного. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 20:03 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Andy_OLAP, спасибо за совет :) но мне нужны как раз ИЗМЕНЕННЫЕ данные из БД :) видимо, таки пойду допиливать клиентское приложение для вызова нотификации после коммита основной операции ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 20:06 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Vadim Romanenko- multipleactiveresultsets=True; Так у Вас же режим MARS включен. Ну и в соединение идут разные сеансы из кэша. В рамках одного сеанса ставите блокировку, в рамках другого ждете через ExecuteReader, через 30 секунд достижение лимита и создается новый сеанс без ошибки (и никакой обработки и повторной попытки) - и в рамках его команда выполняется. "Чтобы свести к минимуму затраты и повысить производительность, SqlClient кэширует сеанс режима MARS в рамках соединения. Кэш может содержать максимум 10 сеансов режима MARS. Это значение не может быть изменено пользователем. При достижении лимита сеансов создается новый сеанс - ошибка не формируется. Сам кэш и содержащиеся в нем сеансы принадлежат одному соединению, они не могут использоваться в нескольких соединениях". Ну так нормально. 30 секунд пользователи подождут. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 20:10 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Vadim RomanenkoAndy_OLAP, спасибо за совет :) но мне нужны как раз ИЗМЕНЕННЫЕ данные из БД :) видимо, таки пойду допиливать клиентское приложение для вызова нотификации после коммита основной операции Не нужно допиливать. Не пользуйтесь текущей conn as OleDbConnection, а создавайте явно новый conn2 as OleDbConnection внутри OleDbDataReader ExecSQL. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 20:11 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Andy_OLAP, А текущее предварительно закрывайте, чтобы транзакция отпустила и изменения зафиксировались. С другой стороны Вам этот ID и нужен, а для нового соединения он возможно будет другой. В общем, нужно проверять. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 20:14 |
|
Разное время выполнения запроса из C# и SQL Server Management Studio
|
|||
---|---|---|---|
#18+
Andy_OLAPVadim Romanenko- multipleactiveresultsets=True; Так у Вас же режим MARS включен. Ну и в соединение идут разные сеансы из кэша. В рамках одного сеанса ставите блокировку, в рамках другого ждете через ExecuteReader, через 30 секунд достижение лимита и создается новый сеанс без ошибки (и никакой обработки и повторной попытки) - и в рамках его команда выполняется. "Чтобы свести к минимуму затраты и повысить производительность, SqlClient кэширует сеанс режима MARS в рамках соединения. Кэш может содержать максимум 10 сеансов режима MARS. Это значение не может быть изменено пользователем. При достижении лимита сеансов создается новый сеанс - ошибка не формируется. Сам кэш и содержащиеся в нем сеансы принадлежат одному соединению, они не могут использоваться в нескольких соединениях". Ну так нормально. 30 секунд пользователи подождут. Вах! Спасибо, не знал. Честно говоря, даже не знаю - кто и когда добавил этот параметр в конфиг проекта(-ов). Connection String мигрирует между проектами. В любом случае. Всем еще раз огромное спасибо за помощь! Без коллективного разума я бы, наверное, эту проблему или не решил, или попал бы в дурку (в кругу очевидного-невероятного) или еще чего. Проблема решена - через вызов веб-сервиса после коммита основной операции. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 20:40 |
|
|
start [/forum/topic.php?all=1&fid=18&tid=1355394]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
107ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
66ms |
get tp. blocked users: |
1ms |
others: | 337ms |
total: | 557ms |
0 / 0 |