powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Принудительный ordered scan по временной таблице
62 сообщений из 62, показаны все 3 страниц
Принудительный ordered scan по временной таблице
    #39879207
Eleanor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день,

Заранее спасибо за любые предложения.

Разбираюсь с дедлоками между параллельными вставками в таблицу.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
INSERT INTO dbo.TaskQueue 
	SELECT *
	FROM #TaskQueue_Sorted A
	WHERE NOT EXISTS (
						SELECT 1
						FROM dbo.TaskQueue B WITH (UPDLOCK, ROWLOCK, HOLDLOCK)
						WHERE A.UserId = B.UserId
							AND A.TaskQueueFunctionTypeId = B.TaskQueueFunctionTypeId
							AND A.TaskQueueTypeId = B.TaskQueueTypeId
							AND A.ReferenceId = B.ReferenceId
							AND A.PlannedBeginDate = B.PlannedBeginDate
							AND B.TaskQueueStateId IN (1, 2, 3)
					)



Вставка происходит, только если вставляемых записей еще нет в таблице.
Однако, при проверке наличия записи, блокировки на ключи поискового индекса IDX_TaskQueue_ReferenceId_UserId (ReferenceId, TaskQueueFunctionTypeId, TaskQueueTypeId, PlannedBeginDate, UserId, TaskQueueStateId) в разных потоках накладываются в разном порядке и возникают дедлоки.

#TaskQueue_Sorted кластеризован по тем же полям, что и индекс IDX_TaskQueue_ReferenceId_UserId, но в плане он сканируется с Ordered = False.

Можно ли как-то сделать скан #TaskQueue_Sorted сортированным, чтобы не было дедлоков?
План запроса приложила.

Если просто добавить в запросе Order by, то он в запросе добавляется слишком поздно, сразу после Nested Loops.
Merge join, конечно, даст искомый ordered = true, но сканировать IDX_TaskQueue_ReferenceId_UserId - это слишком.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879223
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eleanor,
а что вы этим добиваетесь? в EXISTS... особенно в контексте "вставок"
авторFROM dbo.TaskQueue B WITH (UPDLOCK, ROWLOCK, HOLDLOCK)
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879233
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EleanorМожно ли как-то сделать скан #TaskQueue_Sorted сортированным
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
INSERT INTO dbo.TaskQueue 
	SELECT *
	FROM (select top (cast(0x7fffffffffffffff as bigint)) * from #TaskQueue_Sorted order by ...) A
	WHERE NOT EXISTS (
						SELECT 1
						FROM dbo.TaskQueue B WITH (UPDLOCK, ROWLOCK, HOLDLOCK)
						WHERE A.UserId = B.UserId
							AND A.TaskQueueFunctionTypeId = B.TaskQueueFunctionTypeId
							AND A.TaskQueueTypeId = B.TaskQueueTypeId
							AND A.ReferenceId = B.ReferenceId
							AND A.PlannedBeginDate = B.PlannedBeginDate
							AND B.TaskQueueStateId IN (1, 2, 3)



Почему INSERT, а не MERGE?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879278
Eleanor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

Спасибо.
C MERGE сложнее запись, потому что уже появилась бездумная привычка предварительно фильтровать целевую таблицу в CTE (иначе на некоторых условиях match, не помню каких, возникал scan).
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879296
Андрей Юниор
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EleanorC MERGE сложнее запись, потому что уже появилась бездумная привычка предварительно фильтровать целевую таблицу в CTE
Вопрос не по теме. Так стоит или не стоит предварительно фильтровать целевую таблицу в CTE при MERGE? Я так делаю даже без явной необходимости...
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879431
Руслан Дамирович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ЮниорEleanorC MERGE сложнее запись, потому что уже появилась бездумная привычка предварительно фильтровать целевую таблицу в CTE
Вопрос не по теме. Так стоит или не стоит предварительно фильтровать целевую таблицу в CTE при MERGE? Я так делаю даже без явной необходимости...
стоит, если например, нужно перезагружать таблицу полностью по фильтру
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
WITH
cte AS (
  SELECT
    [month],
    [id] 
  FROM
    [dst]
  WHERE
    [month] = '20191001'
)
MERGE INTO
  cte
USING
  src
ON (
   src.[id] = cte.[id] )
WHEN MATCHED THEN UPDATE SET ...
WHEN NOT MATCHED BY TARGET THEN INSERT ( ... ) VALUES ( ... )
WHEN NOT MATCHED BY SOURCE THEN DELETE
;
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879501
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EleanorC MERGE сложнее записьКак по мне, то это дело вкуса.
Зато у MERGE гибче OUTPUT и не нужно явно указывать updlock.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879507
Андрей Юниор
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Руслан Дамировичстоит, если например, нужно перезагружать таблицу полностью по фильтру
Когда по фильтру - да. У меня есть такие слияния: по месяцам, по кварталам с составными ключами.

А в таком случае:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
DECLARE @id INT = 1,
    @Name NVARCHAR(255) = 'Name';

WITH Trg AS (SELECT Id, Name
             FROM SomeTable
             WHERE Id = @Id),
    Src AS (SELECT @Id AS Id, @Name AS Name)
MERGE Trg AS T
USING Src AS S
ON (T.Id = S.Id)
WHEN NOT MATCHED BY TARGET
    THEN
    INSERT (Id, Name)
    VALUES (S.Id, S.Name)
WHEN MATCHED
    AND NOT (T.Name = S.Name)
    THEN
    UPDATE
    SET T.Name = S.Name;


это вредно? Смысл хоть какой-то есть?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879510
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ЮниорРуслан Дамировичстоит, если например, нужно перезагружать таблицу полностью по фильтру
Когда по фильтру - да. У меня есть такие слияния: по месяцам, по кварталам с составными ключами.

А в таком случае:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
DECLARE @id INT = 1,
    @Name NVARCHAR(255) = 'Name';

WITH Trg AS (SELECT Id, Name
             FROM SomeTable
             WHERE Id = @Id),
    Src AS (SELECT @Id AS Id, @Name AS Name)
MERGE Trg AS T
USING Src AS S
ON (T.Id = S.Id)
WHEN NOT MATCHED BY TARGET
    THEN
    INSERT (Id, Name)
    VALUES (S.Id, S.Name)
WHEN MATCHED
    AND NOT (T.Name = S.Name)
    THEN
    UPDATE
    SET T.Name = S.Name;



это вредно? Смысл хоть какой-то есть?

Сравните планы.
Думаю, они будут идентичны.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879529
Фотография StarikNavy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eleanor,

Д.Короткевич рекомендовал все таки не использовать MERGE
(кроме удобства написания, все аналогично, только есть ряд покапотных глюков)

вам точно (UPDLOCK, ROWLOCK, HOLDLOCK) внутри эксиста нужны?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879534
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
StarikNavy,

дык подкапотность возникает, если не читать справку, а делать "по аналогии". Что, в общем-то, недопустимо.

Проблема у автора возникает из-за этого:

INSERT INTO dbo.TaskQueue
SELECT *
FROM #TaskQueue_Sorted A
WHERE NOT EXISTS (
SELECT 1
FROM dbo.TaskQueue B WITH (UPDLOCK, ROWLOCK, HOLDLOCK)

Взаимоисключающие блокировки сами напрашиваются. Запрос надо разделить на две части - в первой произвести выборку пригодных для вставки строк, например, во временную таблицу или путем удаления из исходной таблицы, во второй части выполнить вставку этих строк. Даже при прочтении кода будет проще понять - что намеревался сделать автор.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879544
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовЗапрос надо разделить на две части - в первой произвести выборку пригодных для вставки строк, например, во временную таблицу или путем удаления из исходной таблицы, во второй части выполнить вставку этих строк.А теперь расскажите нам, каким образом обеспечить сохранность пригодности для вставки в целевую таблицу строк, отобранных во временную таблицу?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879626
Eleanor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовПроблема у автора возникает из-за этого:

В чем была проблема, invm уже помог исправить. Дедлоков на вставках больше нет.
Очень приятно, что на форуме есть люди подобного уровня.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879814
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmВладислав КолосовЗапрос надо разделить на две части - в первой произвести выборку пригодных для вставки строк, например, во временную таблицу или путем удаления из исходной таблицы, во второй части выполнить вставку этих строк.А теперь расскажите нам, каким образом обеспечить сохранность пригодности для вставки в целевую таблицу строк, отобранных во временную таблицу?

Точно так же как достигается повторяемость чтения в подзапросе с сортировкой, полагаю. Не вижу разницы.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879816
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eleanor,

недостатком этого решения является то, что вы будете вынуждены заставлять" дуть ветер " в одну сторону при обновлениях этой таблицы из других процедур другими запросами. Т.е. равновесие, образно говоря, такого запроса будет неустойчивым, хорошо работать в частном случае.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879821
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Переписать эту дичь на LEFT JOIN и убрать WITH (UPDLOCK, ROWLOCK, HOLDLOCK)
Сортировать это костыль
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879837
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовТочно так же как достигается повторяемость чтения в подзапросе с сортировкой, полагаю. Не вижу разницы.Т.е. в итоге получится исходный запрос, только заполняться будет временная таблица. Потом уже из этой временной переливаться в основную. И все это в явной транзакции.
В чем профит?

PS: Рекомендую поразмышлять - зачем нужны хинты updlock и holdlock. Подсказка: рассмотрите вариант, когда параллельные сессии обрабатывают одну и ту же строку, которой нет в целевой таблице.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879843
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

автор обрабатывают одну и ту же строку, которой нет в целевой таблице.
целевая таблица TaskQueue , запрос на записей которых нет из TaskQueue - их не будет для всех сессий
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879852
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKцелевая таблица TaskQueue , запрос на записей которых нет из TaskQueue - их не будет для всех сессийТеперь подумайте о последствиях.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879860
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKПереписать эту дичь на LEFT JOIN и убрать WITH (UPDLOCK, ROWLOCK, HOLDLOCK)
Сортировать это костыль

Интересный вариант.

invm - хорошим будет тот способ, который не использует сортировки и хинты, т.к. они не являются обычной практикой. Костыль, как правильно подмечено. Т.е. другой разработчик ничего не зная о том, что при обращении к этой таблице требуется обязательная сортировка можно создать взаимоблокировки простым запросом.

Для быстрого исправления, наверное, можно применить хинты.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879862
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmTaPaKцелевая таблица TaskQueue , запрос на записей которых нет из TaskQueue - их не будет для всех сессийТеперь подумайте о последствиях.
сдаюсь.
До момента вставки первого их не будет ни для кого, что будет под (UPDLOCK, ROWLOCK, HOLDLOCK) ? всё?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879870
Eleanor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосовнедостатком этого решения является то, что вы будете вынуждены заставлять" дуть ветер " в одну сторону при обновлениях этой таблицы из других процедур другими запросами. Т.е. равновесие, образно говоря, такого запроса будет неустойчивым, хорошо работать в частном случае.
В данной системе дедлоки на вставках относительно частые, а на обновлениях 1-2 раза в сутки. Связано с разными размерами пачек и разной частотой вызова разных ХП.

Не ставлю целью на 100% избавиться от всех дедлоков. Все равно в случае ошибок идут повторные вызовы.
Система в целом очень подвержена дедлокам, и часто приходится с ними разбираться, т.к. разработчики практически любое действие выполняют в 10 потоках на нескольких машинах.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879879
Eleanor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKПереписать эту дичь на LEFT JOIN и убрать WITH (UPDLOCK, ROWLOCK, HOLDLOCK)
Сортировать это костыль
Можно и переписать, но подсказки убирать не надо. План запроса в итоге не изменяется.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879884
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eleanor,

в моем случае наилучшим оказалось решение с раздельной подготовкой данных и выполнением обновления. Поэтому и предложил.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879888
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKinvmпропущено...
Теперь подумайте о последствиях.
сдаюсь.
До момента вставки первого их не будет ни для кого, что будет под (UPDLOCK, ROWLOCK, HOLDLOCK) ? всё?

под UPDLOCK + HOLDLOCK будут range локи, не дающие "завершить" exists по одним и тем же отсутствующим записям, т.е. вторая сессия будет ждать на range локи, пока первая не разберется, вставлять ли новую запись в справочник или нет.


ЗЫ

Range локи накладываются на предыдущую запись, что приводит к двум проблемам

1. При попытке вставить две разные отсутствующие записи в один пустой диапазон ключей (например, есть записи 1 и 5, а вставляются в разных коннектах 2 и 3), получим ожидание до конца 1-й транзакции

2. При попытке вставить две записи, одна из которых уже есть а другая стоит в пустом диапазоне справа от нее (например, есть запись 2 и 5 пытаемся вставить 2 и 3), получим ожидание до конца 1-й транзакции


Если нет удалений, то со второй проблемой можно справиться "двухфазным" not exists

Сначала без (UPDLOCK, ROWLOCK, HOLDLOCK) выбираем записи которых нет в отдельную # таблицу, а потом
из # таблицы вставляем записи с повторной проверкой, но уже с (UPDLOCK, ROWLOCK, HOLDLOCK)
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879906
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосовinvm - хорошим будет тот способ, который не использует сортировки и хинты, т.к. они не являются обычной практикой.Хорошим будет способ, который обеспечивает наиболее эффективное решение, а не наиболее соответствующий догмам.
И вы так и не ответили в чем профит перекладывания во временную таблицы в данном конкретном случае.

TaPaKсдаюсь.При параллельной вставке updlock+holdlock гарантирует отсутствие дубликатов.
Либо отсутствие ругани о нарушении уникальности, если есть уникальный индекс
Либо отсутствие предупреждения, если есть уникальный индекс с IGNORE_DUP_KEY = ON

msLexRange локи накладываются на предыдущую записьНа следующую.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879908
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
msLexRange локи накладываются на предыдущую записьНа следующую.

точно, все время путаю.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879909
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

я же писал - в чем профит. Не нужна неочевидная стороннему разработчику сортировка в запросе и не требуется поддерживать сортировку в новых запросах. Кроме того, можно не перекладывать, а удалить лишнее.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879912
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmВладислав Колосовinvm - хорошим будет тот способ, который не использует сортировки и хинты, т.к. они не являются обычной практикой.Хорошим будет способ, который обеспечивает наиболее эффективное решение, а не наиболее соответствующий догмам.
И вы так и не ответили в чем профит перекладывания во временную таблицы в данном конкретном случае.

TaPaKсдаюсь.При параллельной вставке updlock+holdlock гарантирует отсутствие дубликатов.
Либо отсутствие ругани о нарушении уникальности, если есть уникальный индекс
Либо отсутствие предупреждения, если есть уникальный индекс с IGNORE_DUP_KEY = ON

msLexRange локи накладываются на предыдущую записьНа следующую.
почему не накладывать это на получатель?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879916
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосовя же писал - в чем профит. Не нужна неочевидная стороннему разработчику сортировка в запросе и не требуется поддерживать сортировку в новых запросах. Кроме того, можно не перекладывать, а удалить лишнее.


Слишком много слов, давайте вы на примере покажите как без not exists вы решаете следующую задачу

есть таблица
Код: sql
1.
create table dbo.dict(id int not null primary key) 



нужно реализовать процедуру
Код: sql
1.
create proc dbo.dict_add


принимающую на вход список id и добавляющую в dbo.dict, те что отсутствуют.
процедура вызывается во много потоков, входящие id в разных потоках могут совпадать.


для простоты (что бы не генерить дополнительных сущностей), список id будет # таблица
Код: sql
1.
create table #t(id int not null primary key) 


создаваемая и заполняемая вне этой процедуры
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879918
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKinvmпропущено...
Хорошим будет способ, который обеспечивает наиболее эффективное решение, а не наиболее соответствующий догмам.
И вы так и не ответили в чем профит перекладывания во временную таблицы в данном конкретном случае.

пропущено...
При параллельной вставке updlock+holdlock гарантирует отсутствие дубликатов.
Либо отсутствие ругани о нарушении уникальности, если есть уникальный индекс
Либо отсутствие предупреждения, если есть уникальный индекс с IGNORE_DUP_KEY = ON

пропущено...
На следующую.
почему не накладывать это на получатель?

потому что между exists (или left join) и insert проходит достаточно времени, чтобы другой поток вставил отсутствующие записи
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879944
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLexTaPaKпропущено...

почему не накладывать это на получатель?

потому что между exists (или left join) и insert проходит достаточно времени, чтобы другой поток вставил отсутствующие записи
т.е. две транзакции в serializable на получателе смогут вот в тот фокус про достаточно времени?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879949
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKт.е. две транзакции в serializable на получателе смогут вот в тот фокус про достаточно времени?

конечно, можете проверить
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879953
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLexTaPaKт.е. две транзакции в serializable на получателе смогут вот в тот фокус про достаточно времени?

конечно, можете проверить
а разве не сразу получение всех блокировок, а потом выполнение?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879958
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLexTaPaKт.е. две транзакции в serializable на получателе смогут вот в тот фокус про достаточно времени?

конечно, можете проверить


вот вам простой репро

создаем таблицу справочник
Код: sql
1.
create table dbo.dict(id int not null primary key) 




и в двух (уже достаточно) потоках запускаем конкурентную вставку с serializable на получателе

Код: 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.
declare @id int = 0

while 1=1
begin
	begin tran
	begin try
		/*выбираем id+1 ключ для имитации конкурентной вставки*/
		select top 1 
			@id = id+1
		from dbo.dict
		order by 
			id desc


		insert dbo.dict with(holdlock, rowlock, updlock) (
			id
		) 
		select 
			@id
		where 
			not exists (
				select *
				from dbo.dict
				where 
					id = @id
			)
		commit tran
	end try
	begin catch 
		rollback tran
		;throw 
	end catch 
end 



переносим хинты ниже и снова запускаем в двух сессиях

Код: 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.
declare @id int = 0

while 1=1
begin
	begin tran
	begin try
		/*выбираем id+1 ключ для имитации конкурентной вставки*/
		select top 1 
			@id = id+1
		from dbo.dict
		order by 
			id desc


		insert dbo.dict  (
			id
		) 
		select 
			@id
		where 
			not exists (
				select *
				from dbo.dict with(holdlock, rowlock, updlock)
				where 
					id = @id
			)
		commit tran
	end try
	begin catch 
		rollback tran
		;throw 
	end catch 
end 
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879965
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKа разве не сразу получение всех блокировок, а потом выполнение?


нет, конечно.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879969
Cristiano_Rivaldo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если требуется исключить повторяющиеся - то почему бы не повесить уникальный констрейнт на таблицу ?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879970
Cristiano_Rivaldo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Cristiano_Rivaldo,

Ничего лочить не надо будет. И дублей гарантированно не будет...
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879971
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cristiano_RivaldoЕсли требуется исключить повторяющиеся - то почему бы не повесить уникальный констрейнт на таблицу ?
и откатывать всю транзакцию, при его нарушении?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879974
Cristiano_Rivaldo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
msLex,

Нужно написать грамотный блок обработки ошибок
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879975
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосовя же писал - в чем профит. Не нужна неочевидная стороннему разработчику сортировка в запросеДля заботы о стронних разработчиках придумали комментарии.
Владислав Колосовне требуется поддерживать сортировку в новых запросах.Зачем ее там поддерживать?
Владислав КолосовКроме того, можно не перекладывать, а удалить лишнее.Задача - добавить из источника строки, отсутствующие в целевой таблице.
Что тут лишнее, которое можно удалить?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879977
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cristiano_RivaldomsLex,

Нужно написать грамотный блок обработки ошибок

до блока ошибок, вставка в таблицу уже откатится
если вставлять одну запись, вроде и не так жалко (хотя это уже двойная вставка в лог)
а если за раз нужно вставить отсутствующие из 10000 входящих записей и вставка упадет из-за 1-й последней записи?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879982
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLex,

при многопоточности должны быть очереди в любом проявлении - блокировки страниц или блокировки уровня приложения. Позвольте мне воздержаться от написания примера, мозг и так взрывается :) Ищу решение для каскадного удаления.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879985
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

Зачем ее там поддерживать?

Вот в этом и вопрос - разве одновременной выполнение другого запроса к этой же таблице не будет потенциальным источником взаимоблокировок? В нем ведь последовательность наложения блокировок не будет упорядоченной.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879986
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLex,

Да вы правы, спасибо. В последнее время на такое просто вешаем игнор и фиг с ним
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879988
Cristiano_Rivaldo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
msLex,

Да - от ошибки нарушения уникальности никуда не денешься...
Но есть практики,которые позволяют заинсертить большое количество данных в максимально короткое время.
Чем быстрее завершится insert - тем меньше шансов на дубли.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879990
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmЗадача - добавить из источника строки, отсутствующие в целевой таблице.
Что тут лишнее, которое можно удалить?

Поясню. Во временной таблице находится набор потенциально избыточных данных, это следует из запроса ниже, который фильтрует эти избыточные данные. Если избыточные данные удалить из временной таблице перед вставкой и исключить из запроса фильтр, то проблема взаимоблокировок не появится.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879992
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовmsLex,

при многопоточности должны быть очереди в любом проявлении - блокировки страниц или блокировки уровня приложения.

т.е. блокировки уровня ключей вас не устраивают, а страницами пожалуйста



Владислав КолосовПозвольте мне воздержаться от написания примера, мозг и так взрывается :)
Я не в коем случае не заставляя вас, просто хотелось понять на примере простого кода о чем вы говорите.
Мне до сих пор не понятно как вы решаете проблему многопоточной конкурентной вставки в уникальный ключ.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39879995
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cristiano_RivaldomsLex,

Да - от ошибки нарушения уникальности никуда не денешься...

денешься. один из вариантов показан выше
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880000
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKmsLex,

Да вы правы, спасибо. В последнее время на такое просто вешаем игнор и фиг с ним
Если мы на такое повесили бы игнор, у нас бы ошибки уникальности падали бы раз в 5 минут.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880002
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовinvmЗадача - добавить из источника строки, отсутствующие в целевой таблице.
Что тут лишнее, которое можно удалить?

Поясню. Во временной таблице находится набор потенциально избыточных данных, это следует из запроса ниже, который фильтрует эти избыточные данные. Если избыточные данные удалить из временной таблице перед вставкой и исключить из запроса фильтр, то проблема взаимоблокировок не появится.
удаление избыточных данных не поможет в проблеме с уникальностью, отсутствующие в таблице данные по прежнему могут начать вставляться одновременно из двух параллельных потоков.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880003
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLexTaPaKmsLex,

Да вы правы, спасибо. В последнее время на такое просто вешаем игнор и фиг с ним
Если мы на такое повесили бы игнор, у нас бы ошибки уникальности падали бы раз в 5 минут.
ошибка? я про ignore dup key
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880010
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKmsLexпропущено...

Если мы на такое повесили бы игнор, у нас бы ошибки уникальности падали бы раз в 5 минут.
ошибка? я про ignore dup key
а, ясно.

ну во-первых, он тоже вешает тот же holdlock
во-вторых, работает медленнее (появляются какие-то дополнительные накладные расходы).
плюс, как уже говорили, спамит варнингами
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880012
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLexTaPaKпропущено...

ошибка? я про ignore dup key
а, ясно.

ну во-первых, он тоже вешает тот же holdlock
во-вторых, работает медленнее (появляются какие-то дополнительные накладные расходы).
плюс, как уже говорили, спамит варнингами
У меня получилось в разы быстрее при отказе от exists, особенно на больших объёмах

на варнинги всё равно в общем
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880013
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLex,

Код: sql
1.
Мне до сих пор не понятно как вы решаете проблему многопоточной конкурентной вставки в уникальный ключ.



Да, не подумал. конкуренции у меня нет на самом деле, т.к. включается sp_getapplock или выполнение по расписанию. Борьба происходила с deadlock, вызванными запросом внутри себя. Возможно у меня сортировкофобия, не знаю :)
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880014
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKУ меня получилось в разы быстрее при отказе от exists, особенно на больших объёмах
очень, очень странно
физически он проделывает тоже самое, что и not exists

может у вас not exists в скан сваливлся? у нас еще forceseek четвертым хинтом обязательно стоит.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880015
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовmsLex,

Код: sql
1.
Мне до сих пор не понятно как вы решаете проблему многопоточной конкурентной вставки в уникальный ключ.




Да, не подумал. конкуренции у меня нет на самом деле, т.к. включается sp_getapplock или выполнение по расписанию. Борьба происходила с deadlock, вызванными запросом внутри себя. Возможно у меня сортировкофобия, не знаю :)

если у вас допустима синхронизация на уровне sp_getapplock, то вам, конечно, не нужны все эти holdlock-и
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880057
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовПоясню. Во временной таблице находится набор потенциально избыточных данных, это следует из запроса ниже, который фильтрует эти избыточные данные. Если избыточные данные удалить из временной таблице перед вставкой и исключить из запроса фильтр, то проблема взаимоблокировок не появится.Чтобы избавиться от избыточных данных, нужно определить, что они избыточные.
Для этого нужно проделать те же самые манипуляции с целевой таблицей, что и в стартовом посте. В результате получите те же дедлоки.

Вы в своих решениях принципиально не хотите учитывать конкурентность выполнения запросов?
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880080
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

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

Для запросов вида update table1 where exists (select * from table1) можно получить дедлок единственным запросом.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880082
Ftt330
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
msLexи откатывать всю транзакцию, при его нарушении?
Вставляйте по строке за раз :)
Для соблюдения уникальности в СУБД придуманы unique констрейнты.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880100
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ftt330msLexи откатывать всю транзакцию, при его нарушении?
Вставляйте по строке за раз :)
Для соблюдения уникальности в СУБД придуманы unique констрейнты.Ваш метод организации конкурентной вставки понятен, но далеко не у всех у базы один пользователь.
...
Рейтинг: 0 / 0
Принудительный ordered scan по временной таблице
    #39880105
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосовя уже ответил, что дедлоки в моем случае были вызваны не конкурентностью между потоками, а конкурентностью внутри самого запроса. Поэтому, если ситуации с одновременным выполнением нет, то можно производить все действия, которые я описал.Тогда непонятно зачем вообще предлагать решение заранее зная, что оно не подойдет?
Что такое "конкурентностью внутри самого запроса"?
Владислав КолосовДля запросов вида update table1 where exists (select * from table1) можно получить дедлок единственным запросом.Как это относится к запросу ТС?
...
Рейтинг: 0 / 0
62 сообщений из 62, показаны все 3 страниц
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Принудительный ordered scan по временной таблице
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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