Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
Доброго дня! Есть небольшая по размеру временная таблица TmpT , используется как промежуточная для вставки в "рабочую" WrkBigTable . Наполняемость многократно варьируется - от 1 до 1000 строк. Несколько клиентов (через разные хранимки или напрямую) накидывают в TmpT свои рекордсеты, маркированные ключевым полем (KeyField). Клиентами запускается одна и та же хранимая процедура с соответствующим полю KeyField значением параметра - выбирает из TmpT записи, обрабатывает их и кидает в WrkBigTable . Суть проблемы: для получения значения KeyField происходит выборка: Код: sql 1. . Вставка записей в TmpT, их выборка из TmpT и удаление,- совершенно ни как не связаны. В какой-то момент начинается конфликт. Причём, похоже, всё сходится именно на несчастной TmpT, а именно её KeyField . По KeyField есть первичный ключ в связке ещё с одним полем. Почесав затылок и вспомним лекции Дмитрия Короткевича, не придумал ни чего лучшего, как создать отдельный некластерный индекс по KeyField. Индекс получился страшным (на 1000 обновлений всего 500 seek-ов), но сервер использует его в estimated plan для select @NewKey = isnull(max(KeyField),0)+1 From TmpT WITH (UPDLOCK HOLDLOCK) (!!!!) Насколько удачным можно считать такое решение? С одной стороны, индекс волочиться "мёртвым хвостом". С другой,- это, на мой взгляд, единственное решение в рамках неизменяемости архитектуры базы и приложения... -------------------------- No ROM Basic... Как-то так (на вскидку, не проверял ;-) ) : Код: sql 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2019, 18:15 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
SIMPLicity_, Я бы это сделал через Service Broker для разделения отправителя и получателя. На стороне инициатора помещаете данные в очередь, а на стороне получателя забираете из очереди и обрабатываете. Используйте группы, чтобы из одной очереди могли забирать разные получатели или сформируйте несколько очередей. Кроме того, можно накопленные сообщения обрабатывать "оптом". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.02.2019, 10:41 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
Владислав КолосовSIMPLicity_, Я бы это сделал через Service Broker для разделения отправителя и получателя. На стороне инициатора помещаете данные в очередь, а на стороне получателя забираете из очереди и обрабатываете. Используйте группы, чтобы из одной очереди могли забирать разные получатели или сформируйте несколько очередей. Кроме того, можно накопленные сообщения обрабатывать "оптом". Спасибо за комментарий, но этот вариант в данном случае неприемлем - слишком велико время прохождения всей цепочки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.02.2019, 14:19 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
SIMPLicity_, еще один простой способ разделить читателей и писателей - превратить таблицу в InMemory. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.02.2019, 16:21 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
SIMPLicity_Вставка записей в TmpT, их выборка из TmpT и удаление,- совершенно ни как не связаны. В какой-то момент начинается конфликт. Причём, похоже, всё сходится именно на несчастной TmpT, а именно её KeyField .Так конфликт происходит при получении новой KeyField? оно же редко вызывается, по сравнению с вставками в TmpT вообще, правильно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.02.2019, 18:33 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
SIMPLicity_, Тип KeyField принципиален? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.02.2019, 18:50 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
invmSIMPLicity_, Тип KeyField принципиален? Замена на uniqueidentifier?- не, "не катит" .... К тому же это не моя архитектура... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.02.2019, 21:47 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
alexeyvgSIMPLicity_Вставка записей в TmpT, их выборка из TmpT и удаление,- совершенно ни как не связаны. В какой-то момент начинается конфликт. Причём, похоже, всё сходится именно на несчастной TmpT, а именно её KeyField .Так конфликт происходит при получении новой KeyField? оно же редко вызывается, по сравнению с вставками в TmpT вообще, правильно? Конфликт происходит как в момент непосредственного захвата, так и в моменты других операций ... Ошибки спонтанные, плюс ко всему тут замешаны распределённые транзакции. И всё это происходит только на "боевой" базе. Сымитировать не удаётся :( ... Думаю переделать кластерный индекс в некластерный ;-) .... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.02.2019, 21:57 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
SIMPLicity_Конфликт происходит как в момент непосредственного захвата, так и в моменты других операций ... Ошибки спонтанные, плюс ко всему тут замешаны распределённые транзакции. И всё это происходит только на "боевой" базе. Сымитировать не удаётся :(Ну, тут же может быть множество причин... Если даже точно неясно, где блокируется. Можно, конечно, попробовать индекс, вдруг поможет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.02.2019, 23:43 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
SIMPLicity_решение в рамках неизменяемости архитектуры базы и приложения...Насколько неизменяема структура? А бинарники пропатчить? Что, если на TmpT повесить триггер на вставку, который будет сохранять этот isnull(max(KeyField),0)+1 в отдельную таблицу TmpTid из одного поля и из одной записи? Тогда блокировать будет нужно её и читать ключ из неё. TmpT будет на вставку доступна (почти)всегда. Если вместо таблицы TmpTid генерить из триггера create/alter view TmpTid as select KeyField=123 с константой. Тогда блокировка будет связана со схемой, что позволит сместить проблему, но решит ли- неизвестно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.02.2019, 09:26 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
SIMPLicity_Замена на uniqueidentifier?- не, "не катит"Ну и ладно. Что бы предложить чего-нибудь конструктивное, нужно понимать что вы называете "конфликтом". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.02.2019, 12:36 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
SIMPLicity_, Вам ничего не поможет, кроме технологических решений (Inmemory, переключение режима изоляции в вариант версионирования), потому, что запрос сканирует таблицу в поиске максимального значения. Накладывайте tablock, но это создаст узкое горло. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.02.2019, 12:38 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
SIMPLicity_, было подобное. Заменил isnull(max(KeyField),0)+1 на поле identity Но у Вас немного сложнее. Как вариант (чисто теоритически), разделить таблицу на две в одной KeyField как identity, в другой KeyField и значения рекордсетов на первой написать insteadof тригер, в котором в первую заносятся одна строка с получение идентити и вставка данных рекордсетов во вторую ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.02.2019, 13:03 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
Хорошо. А если вынести нового значения KeyField на SEQUENCE? или вариант от HandKot . Индекс по KeyField оставить только для более быстрого поиска, что удалить/перенести ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.02.2019, 13:13 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
invmЧто бы предложить чего-нибудь конструктивное, нужно понимать что вы называете "конфликтом"+1 Дедлок, что ли? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.02.2019, 14:10 |
|
||
|
Борьба с блокировками через индексы...
|
|||
|---|---|---|---|
|
#18+
HandKotКак вариант (чисто теоритически), разделить таблицу на две в одной KeyField как identity, в другой KeyField и значения рекордсетовДа, тоже хотел такое предложить, но непонятно, что всё таки происходит, и в чём проблема, может, совсем в другом, не связанном с этой таблицей и с этим полем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.02.2019, 14:11 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=39776062&tid=1688265]: |
0ms |
get settings: |
11ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
176ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
54ms |
get tp. blocked users: |
2ms |
| others: | 272ms |
| total: | 547ms |

| 0 / 0 |
