Как получить топ-X записей без перекрытия от нескольких заданий? - PullRequest
0 голосов
/ 25 марта 2019

Редактировать: если важно SQL Server 2012

У нас есть таблица, в которой одновременно обрабатывается несколько заданий. Это тот же запрос, который используется в каждой работе. Как мы можем избежать блокировки и перекрытия в запросах?

У нас есть код, который находится в производстве, но тот, кто его создал, ушел, и в запросе нет объяснения.

Я думаю, что CTE (в запросе) важен для этой задачи, но я не смог найти объяснения, почему это может быть. Я не смог выполнить правильный поиск, потому что все результаты, которые я нахожу, получают TOP X, а не TOP X, без наложения, в нескольких потоках.

пример таблицы tmp1:

id | processed 
1  | 0
2  | 0
3  | 0
4  | 1
... 

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

Текущий запрос выглядит так:

WITH tmpIDS AS (
  select top 100 * from tmp1
  where processed = 0
)
INSERT INTO #work (id)
select * from (
 update tmpIDS set processed = 1
output inserted.id
) a;

Все, что появляется после запроса, использует временную таблицу #work или использует идентификатор и фильтр для одной записи в исходной таблице.

Вопрос, на который мы не можем ответить, заключается в том, почему этот запрос написан таким образом. Запланировано несколько заданий, которые выполняют этот запрос одновременно (или достаточно близко), и, насколько мы понимаем, они не выбирают одни и те же записи TOP X.

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

Даже если есть что-то, что я могу прочитать, чтобы найти объяснение, я пойду и прочитаю его, но сам не смог его найти.

1 Ответ

0 голосов
/ 25 марта 2019

Ваш код делает выбор 100 верхних строк, которые не были обработаны, обновляет эти строки, чтобы пометить их как «обработанные», а затем вставляет ids строк, которые были только что обновлены, во временную таблицу, предположительно для обработки.

Это означает, что первое, что происходит, - это то, что строки помечаются как обработанные, поэтому другое задание не появляется и выбирает их для обработки, пока они еще обрабатываются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...