0

I've added a clustered index to some large but necessary temp tables, which has vastly improved the performance of some sluggish slow-running stored procedures. Some of the temp tables have a unique identifier data type, which I understand is good practice because it narrows scope. However, having an IDENTITY column in the temp table also causes an error "Msg 2601" when I attempt to add a clustered index because it causes a unique key violation.

My clustered index:

CREATE UNIQUE CLUSTERED INDEX IDX_TEMPANDetails_BuildNumber 
ON #TEMPANDetails (BuildNumber)

Error message:

Msg 2601 ...
Cannot insert duplicate key row in object 'dbo.#TEMPANDetails' with unique index 'IDX_TEMPANDetails_BuildNumber'. The duplicate key value is (150362).

Is there a workaround that avoids "Msg 2601" error while retaining a narrow scope? A lot of solutions suggest creating a brand new table. Because these temp tables are so large, I'm not keen to recreate them and insert values into every row.

The following potential two work-arounds appeal, because I only INSERT into the columns with duplicates, i.e., the ones that cause "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> ;

Note: (BuildName) is a placeholder.

From this post (https://dba.stackexchange.com/questions/6736/what-does-x-stand-for-in-this-query), I understand that 'X' is the alias for the inline derived table. Elsewhere I read that the query (above) should work if the temp table hasn't been loaded yet (it hasn't). This StackOverflow post is informative, but not directly related to my problem: How can I catch UniqueKey Violation exceptions with EF6 and SQL Server? ...

Could there be a way to handle these violations nicely in SQL Server using a TRY/CATCH block?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Ganymede
  • 1
  • 1
  • 1
    I don't quite understand. Some feedback: 1. If you have an identity column and you haven't manually overwritten it, it will be unique. 2. If data in a column isn't unique, you don't work around it. It's not unique. 3. Uniqueidentifier is not really the best choice for a clustered index. It's four times the size of an INT. In a temp table it makes even less sense because there wouldn't be any reason to have a globally unique identiifer. – Nick.Mc Jun 18 '21 at 00:20
  • Thank you for responding. I'm a n00b and have learned a lot from your response. I really appreciate the feedback. – Ganymede Jun 18 '21 at 02:57
  • Also, a clustered index doesn't have to be unique. The simple solution would be to remove `UNIQUE` from your clustered index creation. But there is some kind of underlying issue here – Nick.Mc Jun 18 '21 at 03:05
  • What exactly do you mean by "narrow scope"? – Nick.Mc Jun 18 '21 at 03:06
  • Also you can use this setting to ignore duplicate values. It is not a solution, it's a way to shine a light on your current issue. https://sqlperformance.com/2019/04/sql-performance/ignore_dup_key-slower-clustered-indexes – Nick.Mc Jun 18 '21 at 03:08
  • Thank you for introducing me to sqlperformance.com. I appreciate the author's focus on testing and data instead of opinion. I have some reading to do. WRT "narrow focus", it was my way of saying that it's desirable to use an IDENTITY column in the first place. My vocabulary is poor. Yes, my clustered indices are no longer unique. I should have thought of that originally before posting. However, one can learn a lot from asking a stupid question as evidenced here. Thank you for taking the time to respond to a n00b. – Ganymede Jun 18 '21 at 04:07
  • All of your questions are excellent. It's only stoopid to spin your wheels or make assumptions. I still don't quite understand what you mean by "narrow focus" but if you can clarify, maybe I can help futher. Or.... perhaps you could explain some more background on what you are trying to do. – Nick.Mc Jun 18 '21 at 04:15

0 Answers0