У нас есть процесс, который генерирует отчет об инвентаризации. На стороне клиента процесс разбивает настраиваемое количество рабочих потоков для создания порции данных для отчета, которая соответствует одному хранилищу из многих (потенциально тысяч, обычно десятков). Каждый рабочий поток вызывает веб-сервис, который выполняет хранимую процедуру.
Процесс базы данных для обработки каждого чанка собирает кучу данных в таблицу #Teorary. В конце каждого блока обработки данные записываются в постоянную таблицу в базе данных tempdb. Наконец, в конце процесса один поток на стороне клиента запрашивает все данные из постоянной таблицы tempdb.
Чем больше пользователей запустят этот отчет, тем медленнее он будет. Я проанализировал активность в базе данных. В какой-то момент я увидел 35 отдельных запросов, все из которых были заблокированы в одной точке процесса. Все эти SPID имели порядка 50 мс ожидания типа LATCH_EX
на ресурсе METADATA_SEQUENCE_GENERATOR (00000010E13CA1A8)
. Один SPID имеет этот ресурс, а все остальные блокируют. Я не нашел ничего об этом ресурсе ожидания в веб-поиске.
Таблица в базе данных tempdb, которую мы используем, имеет IDENTITY(1,1)
столбец. Ожидают ли эти SPID столбца IDENTITY? Какие методы мы могли бы использовать, чтобы уменьшить или устранить блокировку?
Сервер является частью кластера. Сервер работает под управлением 64-разрядной версии SQL Server 2012 Standard Edition с пакетом обновления 1 (SP1) в 64-разрядной версии Windows 2008 R2 Enterprise. Сервер имеет 64 ГБ ОЗУ и 48 процессоров, но база данных может использовать только 16, потому что это стандартная версия.
(Обратите внимание, что я не в восторге от использования постоянной таблицы в базе данных tempdb для хранения всех этих данных. Изменение этого было бы интересной технической и политической задачей, но я открыт для предложений.)
ОБНОВЛЕНИЕ 23.04.2013
Мы открыли дело о поддержке с Microsoft. Я буду держать этот вопрос в курсе, как мы узнаем больше.
ОБНОВЛЕНИЕ 5/10/2013
Инженер службы поддержки SQL Server согласился, что ожидания были вызваны столбцом IDENTITY. Снятие ИДЕНТИЧНОСТИ устранило ожидания. Мы не смогли продублировать проблему в SQL 2008 R2; это произошло только на SQL 2012.
источник
Ответы:
Предполагая, что вы можете изолировать проблему от создания значений идентификаторов (попробуйте удалить этот столбец в качестве теста), я бы порекомендовал следующее:
IDENTITY
свойство из столбца в итоговой таблице.Таким образом, если у вас есть идентификаторы хранилища 3 и 4, вы получите конечные значения идентификаторов, например:
Или что-то похожее на это. Вы поняли идею.
Это исключит необходимость сериализации при
IDENTITY
генерации при сохранении уникальности в конечном результате.В качестве альтернативы, в зависимости от того, как работает процесс, вставьте окончательные рассчитанные значения идентификаторов в таблицы #Teorary. Тогда вы могли бы создать представление, которое
UNION ALL
объединяет их, исключая необходимость вообще копировать данные.источник
IDENTITY
столбец. Мы удалили его из уже широкого кластерного индекса и полностью удалили столбец. Это было не нужно. После этого эти ожидания LATCH_EX ушли. Мы не могли продублировать ожидания на SQL 2008 R2. Эта проблема возникла только в SQL Server 2012.IDENTITY
значения, был переписан для использования нового материала для генерации последовательности, который был новым в 2012 году. В <2012 вы можете увидеть другой тип защелки, хотя, если не было проблем с перфорированием, то, кажется, было регрессия в коде. В любом случае, удалениеIDENTITY
столбца - самая безопасная вещь.(Обновлено в феврале 2019 г.)
Это старый пост, в котором говорится, что мне наконец удалось убедить Microsoft в том, что сам факт этого действительно является дефектом.
Обновление: MS подтвердил дефект и присвоил ему ошибку № 12628722.
Я видел этот пост в ноябре 2018 года, когда мы начали страдать примерно так же после того, как мы обновили Sql Server 2005 до Sql Server 2017. Таблица с 3,3 млн строк, которая раньше занимала 10 секунд для массовой вставки, внезапно начала занимать 10 минут на столах с
Identity
колоннами.Оказывается, есть две проблемы:
Мне потребовалось 4 недели, но сразу после каникул я получил запоздалый подарок от Санты - подтверждение того, что проблема действительно была дефектом.
Есть несколько возможных обходных путей, которые мы нашли, пока это не будет исправлено:
Option (MaxDop 1)
в запросе, чтобы превратить массовую вставку обратно в сериализованный план.Select Cast(MyIdentityColumn As Integer) As MyIdentityColumn
)SELECT...INTO
Обновление: исправление, которое будет реализовывать MS, будет возвращать эти виды вставок обратно, используя
Serialized
план. Это запланировано для Sql Server 2017 CU14 (никаких новостей о других версиях Sql Server - извините!). При реализации Trace Flag 9492 необходимо будет включить либо на уровне сервера, либо черезDBCC TraceOn
.источник