Работоспособный обходной путь кластерного индексирования для Msg 2601, сохраняя при этом узкую область

Я добавил кластеризованный индекс к некоторым большим, но необходимым временным таблицам, что значительно повысило производительность некоторых медленно работающих хранимых процедур. Некоторые из временных таблиц имеют тип данных с уникальным идентификатором, что, как я понимаю, является хорошей практикой, поскольку сужает область действия. Однако наличие столбца IDENTITY во временной таблице также вызывает ошибку Msg 2601, когда я пытаюсь добавить кластеризованный индекс, поскольку это вызывает нарушение уникального ключа.

Мой кластеризованный индекс:

CREATE UNIQUE CLUSTERED INDEX IDX_TEMPANDetails_BuildNumber 
ON #TEMPANDetails (BuildNumber)

Сообщение об ошибке:

Msg 2601 ...
Невозможно вставить повторяющуюся ключевую строку в объект «dbo.#TEMPANDetails» с уникальным индексом «IDX_TEMPANDetails_BuildNumber». Повторяющееся значение ключа (150362).

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

Следующие два потенциальных обходных пути привлекательны, потому что я только ВСТАВЛЯЮ в столбцы с дубликатами, т. Е. Те, которые вызывают Msg 2601:

CREATE TABLE #TEMPANDetails <lots of code> ;

<Option A>

IF NOT EXISTS (SELECT 'X' 
               FROM [dbo].[#TEMPANDetails] AS Target
               WHERE [BuildNumber] = '150362')
   INSERT INTO [dbo].[#TEMPANDetails] ([BuildNumber], [BuildName])
   VALUES ( 'Null', 'Null' )
GO

<Option B>

INSERT INTO [dbo].[#TEMPANDetails] ([BuildNumber], [BuildName])
    SELECT '150362', 'Null'
    WHERE NOT EXISTS (SELECT 'X' FROM [dbo].[#TEMPANDetails]
                      WHERE [BuildNumber] = 'Null')
GO

CREATE UNIQUE CLUSTERED INDEX IDX_TEMPANDetails_BuildNumber 
ON #TEMPANDetails (BuildNumber)

INSERT INTO #TEMPANDetails 
    SELECT DISTINCT <lots of code> ;

Примечание. (BuildName) является заполнителем.

Из этого сообщения (https://dba.stackexchange.com/questions/6736/what-does-x-stand-for-in-this-query), я понимаю, что «X» — это псевдоним встроенной производной таблицы. В другом месте я читал, что запрос (выше) должен работать, если временная таблица еще не загружена (это не так). Этот пост StackOverflow является информативным, но не имеет прямого отношения к моей проблеме: -sql-server">Как перехватывать исключения UniqueKey Violation с помощью EF6 и SQL Server? ...

Может ли быть способ хорошо обрабатывать эти нарушения в SQL Server с помощью блока TRY/CATCH?


person Ganymede    schedule 18.06.2021    source источник
comment
Я не совсем понимаю. Некоторые отзывы: 1. Если у вас есть столбец идентификаторов, и вы не перезаписали его вручную, он будет уникальным. 2. Если данные в столбце не уникальны, вы не сможете обойти это. Это не уникально. 3. Uniqueidentifier — не лучший выбор для кластеризованного индекса. Это в четыре раза больше, чем INT. Во временной таблице это имеет еще меньше смысла, потому что не было бы никаких причин иметь глобально уникальный идентификатор.   -  person Nick.McDermaid    schedule 18.06.2021
comment
Спасибо за ответ. Я n00b и многому научился из вашего ответа. Я очень ценю обратную связь.   -  person Ganymede    schedule 18.06.2021
comment
Кроме того, кластеризованный индекс не обязательно должен быть уникальным. Простым решением было бы удалить UNIQUE из создания вашего кластерного индекса. Но здесь есть какая-то основная проблема   -  person Nick.McDermaid    schedule 18.06.2021
comment
Что именно вы подразумеваете под узкой областью?   -  person Nick.McDermaid    schedule 18.06.2021
comment
Также вы можете использовать этот параметр, чтобы игнорировать повторяющиеся значения. Это не решение, это способ пролить свет на вашу текущую проблему. sqlperformance.com/2019/04/sql-performance/   -  person Nick.McDermaid    schedule 18.06.2021
comment
Спасибо, что познакомили меня с sqlperformance.com. Я ценю внимание автора к тестированию и данным, а не к мнению. Мне нужно кое-что почитать. Узкий фокус WRT, это был мой способ сказать, что желательно использовать столбец IDENTITY в первую очередь. Мой словарный запас беден. Да, мои кластеризованные индексы больше не уникальны. Я должен был подумать об этом изначально, прежде чем публиковать. Тем не менее, можно многому научиться, задав глупый вопрос, как показано здесь. Спасибо, что нашли время ответить на n00b.   -  person Ganymede    schedule 18.06.2021
comment
Все ваши вопросы превосходны. Глупо крутить колеса или делать предположения. Я до сих пор не совсем понимаю, что вы подразумеваете под узким фокусом, но если вы можете уточнить, возможно, я смогу помочь дальше. Или .... возможно, вы могли бы объяснить еще немного о том, что вы пытаетесь сделать.   -  person Nick.McDermaid    schedule 18.06.2021