March 27, 2012 at 11:05 am
I have a Unique Constraint on a Clustered table named dbo.MyWidgetTable in
the form of :
CONSTRAINT UK_Widget_UID UNIQUE NONCLUSTERED (Widget_UID, WidgetColor)
This unique constraint is largely in place to assist with foreign key
relationships as the parent to child tables.
NOTE: There is an existing clustered index in place on the same table.
I also have two nonclustered indexes in the form of:
CREATE NONCLUSTERED INDEX IX_CreatedAt ON dbo.MyWidgetTable
(Widget_UID, WidgetColor, CreatedAt)
CREATE NONCLUSTERED INDEX IX_CreatedAt ON dbo.MyWidgetTable
(Widget_UID, WidgetColor, WidgetStatusFID)
As one can see, the nonclustered indexes overlap the unique constraint.
Is there a way around this overlapping index issue?
Because if I change the UNIQUE NONCLUSTERED index to have key columns
CreatedAt, WidgetStatusFID...and then try to create the following foreign key
constraint:
ALTER TABLE [dbo].[MyWidgetStatusTable] WITH NOCHECK ADD CONSTRAINT
[FK_MyWidgetStatusTable_MyWidgetTable] FOREIGN KEY([WidgetFID], [WidgetColor])
REFERENCES [dbo].[MyWidgetTable] ([Widget_UID], [WidgetColor])
I get the following error:
Msg 1776, Level 16, State 0, Line 1
There are no primary or candidate keys in the referenced table 'dbo.
MyWidgetTable' that match the referencing column list in the foreign key
'FK_MyWidgetStatusTable_MyWidgetTable'.
Msg 1750, Level 16, State 0, Line 1
Could not create constraint. See previous errors.
My question...I have overlapping indexes...How can I eliminate the
overlapping indexes while still keeping a unique constraint (and the existing
clustered index) in place that allows foreign key constraints to be created?
March 27, 2012 at 11:16 am
You can't add two columns to the unique constraint without changing the uniqueness requirements of the table, and that's a bad thing.
If you really don't want duplicate indexes, reverse the key order of the nonclustered indexes
CREATE NONCLUSTERED INDEX IX_CreatedAt ON dbo.MyWidgetTable
(CreatedAt, Widget_UID, WidgetColor)
CREATE NONCLUSTERED INDEX IX_CreatedAt ON dbo.MyWidgetTable
(WidgetStatusFID, Widget_UID, WidgetColor)
(anything filtering on just Widget_UID, WidgetColor can use the unique constraint)
but if you do that, test and ensure that the queries that use those indexes aren't harmed in the process
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
March 27, 2012 at 1:14 pm
One option to safely rid the database of one of the two overlapping indexes is to INCLUDE the third column in the unique index. Included columns are not considered in uniqueness checks, and any queries using the overalpping index can still be served from the UNIQUE INDEX without doing a lookup to the clustered index, provided the overlapping index was covering the query in the first place.
Example, redefining the UNIQUE INDEX this way...
CREATE UNIQUE NONCLUSTERED INDEX UK_Widget_UID ON dbo.MyWidgetTable
(Widget_UID, WidgetColor) INCLUDE (WidgetStatusFID);
makes this index redundant:
CREATE NONCLUSTERED INDEX IX_WidgetStatusFID ON dbo.MyWidgetTable
(Widget_UID, WidgetColor, WidgetStatusFID)
There are no special teachers of virtue, because virtue is taught by the whole community.
--Plato
Viewing 3 posts - 1 through 2 (of 2 total)
You must be logged in to reply to this topic. Login to reply