Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Эпизодические timeout для простого запроса insert  [new]
Junk
Member

Откуда:
Сообщений: 23
Добрый день!

не могу понять случающуюся ситуацию, помогите разобраться

MS SQL 2012
простеший запрос insert в таблицу из 20 полей, Primary key из двух полей.
В основном такой запрос выполняется 0.05 секунды. Но эпизодически я получаю timeout, выставленный на клиенте в 150 секунд. Причем если повторно сразу же выполнить этот запрос - данные попадут в таблицу практически моментально.
Повторяется такое регулярно, примерно раз в 15-30 минут. База нагружена сильно, порядка 10-15 insertов в секунду идет. параллельных инсертов нет, только чтения параллельно идут и то не часто.

В чем может быть проблема?
21 сен 12, 22:34    [13205057]     Ответить | Цитировать Сообщить модератору
 Re: Эпизодические timeout для простого запроса insert  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32174
Junk
В чем может быть проблема?
Только профайлером посмотреть, или поймать инфу о блокирующем процессе в момент болкировки.
21 сен 12, 22:57    [13205143]     Ответить | Цитировать Сообщить модератору
 Re: Эпизодические timeout для простого запроса insert  [new]
Alexander Titkin
Member

Откуда: Москва
Сообщений: 91
Junk,

File Autogrowth?
22 сен 12, 17:44    [13206796]     Ответить | Цитировать Сообщить модератору
 Re: Эпизодические timeout для простого запроса insert  [new]
В чем може
Guest
Junk
В чем может быть проблема?

в том числе, в том как конкретно клиент эти инсерты отправляет.
и таймауты тоже разные бывают.
22 сен 12, 19:42    [13207165]     Ответить | Цитировать Сообщить модератору
 Re: Эпизодические timeout для простого запроса insert  [new]
Junk
Member

Откуда:
Сообщений: 23
Запустил профайлер на сутки, отсмотрел логи, получил странные интересные вещи:

SP:StmtStarting 491404498 insert into data(_columns_ ) values(_values_ )
3788 mydb sa 52 2012-09-22 22:19:37.587
SP:StmtStarting 279100590 update data set columns = values where pkey = _pkeyid_
3788 mydb sa 53 2012-09-22 22:19:37.590
SP:StmtCompleted 0 2012-09-22 22:19:37.590 279100590 update data set columns = values where pkey = _pkeyid_
0 3788 mydb sa 4 53 2012-09-22 22:19:37.590 1
SP:StmtStarting 491404498 insert into data(_columns_ ) values(_values_ )
3788 mydb sa 52 2012-09-22 22:19:37.590
Lock:Timeout 0 2012-09-22 22:19:37.590 5 - X 0 (25eabc028e1e) 3788 mydb sa 52 2012-09-22 22:19:37.590 0X12000000000125EABC028E1E050007 7 - KEY
Lock:Cancel 20000 2012-09-22 22:19:57.590 5 - X 0 (25eabc028e1e) 3788 mydb sa 52 2012-09-22 22:19:37.590 0X12000000000125EABC028E1E050007 7 - KEY


то есть получается - начинает выполняться insert, потом начинает выполняться update, он же заканчивается, затем почему-то начинает опять выполняться insert с теми же данными и вызывает Exclusive Lock.

В коде софта update этой таблицы вызывается только в одном месте - когда после insert получили exception о том, что primary key уже существует. Соответственно вопрос - если я использую TADOQuery для выполнения insert без явного управления транзакциями, то в момент получения exception у меня запрос всё ещё активен? то есть по идее в коде идет отработка exception и уже после этого вызов TADOQuery с подготовленным update. и этот update начинает блокировать уже вроде бы отработанный с ошибкой insert. Не могу этого понять, подскажите.
23 сен 12, 01:06    [13208384]     Ответить | Цитировать Сообщить модератору
 Re: Эпизодические timeout для простого запроса insert  [new]
и вообще
Guest
Junk,

апдейты висят на отдельном коннекшене? это же spid после "sa"?

и вообще странное решение. "10-15 инсертов в секунду", при этом констрейнту, который можно "обработать" на этапе вставки, позволяется сработать и сгенерить исключение, которое зачем-то гонится аж на клиент, с которого уже отправляется апдейт.
23 сен 12, 03:08    [13208504]     Ответить | Цитировать Сообщить модератору
 Re: Эпизодические timeout для простого запроса insert  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32174
Junk
то есть получается - начинает выполняться insert, потом начинает выполняться update, он же заканчивается, затем почему-то начинает опять выполняться insert с теми же данными и вызывает Exclusive Lock.

В коде софта update этой таблицы вызывается только в одном месте - когда после insert получили exception о том, что primary key уже существует. Соответственно вопрос - если я использую TADOQuery для выполнения insert без явного управления транзакциями, то в момент получения exception у меня запрос всё ещё активен? то есть по идее в коде идет отработка exception и уже после этого вызов TADOQuery с подготовленным update. и этот update начинает блокировать уже вроде бы отработанный с ошибкой insert. Не могу этого понять, подскажите.
Получается, что вы точно не знаете, какие команды у вас вызываются, как получаются результаты и как всё это работает в транзакциях.

Я вообще часто видел ситуации, когда, казалось бы, простое обновление поля в одной записи из приложения приводило к сотням обновлений этой записи из разных коннектов (да, это был ORM!).
Junk
Соответственно вопрос - если я использую TADOQuery для выполнения insert без явного управления транзакциями, то в момент получения exception у меня запрос всё ещё активен? то есть по идее в коде идет отработка exception и уже после этого вызов TADOQuery с подготовленным update. и этот update начинает блокировать уже вроде бы отработанный с ошибкой insert. Не могу этого понять, подскажите.
В принципе это всё вопросы по дельфи и по библиотекам коннекта, как оно работает, аспрашивайте лучьше в специальном форуме. Ну и смотрите чаще профайлер.

С TADOQuery и с дельфи не работал, но в адо процедура продолжает выполняться, пока не будут считаны всек эксепшены и рекордсеты. По поводу отдельного мтейтмента сказать не могу.

Да, что посылается на серевер, тоже в профайлере смотрите. Это вы думаете, что посылается только один INSERT, а там реально возможно куча команд.

Ещё сомнительная архитектура, когда логика вставки/обновления делается на основе эксепешнов - это как минимум очень ресурсоёмко.
23 сен 12, 10:10    [13208574]     Ответить | Цитировать Сообщить модератору
 Re: Эпизодические timeout для простого запроса insert  [new]
Junk
Member

Откуда:
Сообщений: 23
и вообще,

хм, после sa действительно spid. получается в разных, спасибо, что указали, сейчас буду перепроверять!

По поводу обработки exception на вставку - да, я согласен, что эта логика не совсем хорошая, но она была изначально в проекте и не предполагалось, что эти ограничения будут часто вылазить. делать отдельный select на предмет выяснения наличия такого PK получается накладнее.

А вот по поводу переноса обработки exception на server-side - я уже думал запихнуть все это в storedproc и сделать асинхронный вызов для ускорения. Это видимо будет лучший вариант.
23 сен 12, 12:39    [13208720]     Ответить | Цитировать Сообщить модератору
 Re: Эпизодические timeout для простого запроса insert  [new]
invm
Member

Откуда: Москва
Сообщений: 9913
Junk
и вообще,

хм, после sa действительно spid. получается в разных, спасибо, что указали, сейчас буду перепроверять!

По поводу обработки exception на вставку - да, я согласен, что эта логика не совсем хорошая, но она была изначально в проекте и не предполагалось, что эти ограничения будут часто вылазить. делать отдельный select на предмет выяснения наличия такого PK получается накладнее.

А вот по поводу переноса обработки exception на server-side - я уже думал запихнуть все это в storedproc и сделать асинхронный вызов для ускорения. Это видимо будет лучший вариант.
Лучше всего не изобретать велосипед, а использовать инструкцию MERGE. Асинхронный вызов -- самообман. Запрос от этого работать быстрее не станет, только усложните логику на клиенте.
23 сен 12, 13:15    [13208773]     Ответить | Цитировать Сообщить модератору
 Re: Эпизодические timeout для простого запроса insert  [new]
Junk
Member

Откуда:
Сообщений: 23
invm,
спасибо за подсказку, буду переделывать на MERGE.

Всем участвовавшим - огромное спасибо, insert и update действительно исполнялись в разных коннектах, был косячок в коде. Исправил, 2 часа полет нормальный. Буду и дальше следить, но по всей видимости проблема решена
23 сен 12, 14:08    [13208855]     Ответить | Цитировать Сообщить модератору
 Re: Эпизодические timeout для простого запроса insert  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32174
Junk
А вот по поводу переноса обработки exception на server-side - я уже думал запихнуть все это в storedproc и сделать асинхронный вызов для ускорения. Это видимо будет лучший вариант.
Это такой же плохой вариант, как и на клиенте.

Junk
спасибо за подсказку, буду переделывать на MERGE.
Или мердж, или как обычно, с проверкой - оба этих варианта абсолютно идентичны по скорости.
23 сен 12, 15:34    [13209052]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить