It is understood that a table with a clustered index with non-sequential value(s) will cause fragmentation due to page splitting.
In my case, I'm working with a pair of uniqueidentifier
s in a many-to-many table and that is the context for this question.
Consider the following tables:
CREATE TABLE [dbo].[Car](
[CarID] [uniqueidentifier] NOT NULL
...
)
CREATE TABLE [dbo].[Option](
[OptionID] [uniqueidentifier] NOT NULL
...
)
-- This is the table that will be queried
CREATE TABLE [dbo].[Car_Option](
[CarID] [uniqueidentifier] NOT NULL,
[OptionID] [uniqueidentifier] NOT NULL,
[LastEdit] [datetime] NOT NULL
)
I've have read the suggestion to use some sort of surrogate key when using non-sequential identifiers (for example, adding an ID INT
field to [Car_Option]
) to prevent page splitting, however I don't think this applies here and that is what I'm looking to confirm.
If the main lookup value CarID
is not part of Car_Option
's clustered index, I'll need an additional non-clustered index to cover that CarID
column which, I believe, will become just as fragmented as if it were the clustered index because we'd still be inserting non-sequential values. Is this a correct statement?
Option 1
CREATE TABLE [dbo].[Car_Option](
[ID] [int] IDENTITY(1,1) NOT NULL, -- Clustered Index
[CarID] [uniqueidentifier] NOT NULL, -- Non-Clustered Index
[OptionID] [uniqueidentifier] NOT NULL, -- Non-Clustered Index
[LastEdit] [datetime] NOT NULL
)
Option 2
CREATE TABLE [dbo].[Car_Option](
[CarID] [uniqueidentifier] NOT NULL, -- Clustered Index
[OptionID] [uniqueidentifier] NOT NULL, -- Clustered Index
[LastEdit] [datetime] NOT NULL
)
I'm inclined to do Option 2 and put a clustered index on (CarID, OptionID)
.
Question: Is there any advantage to using a surrogate key in Option 1 if we never lookup from it and are only querying from, say, the CarID?
Note: I am aware that index maintenance would be required if using Option 2 non-sequential values
Update 1: It is a requirement to use a Uniqueidentifier
for CarID
and OptionID
. The system is very mature and it would take immense effort to change that. The designs of the Car
and Option
table are not really anything that can reasonibly be changed at this point, the focus is strictly on how using a surrogate key will or will not help my specific query scenario which will look something like this:
SELECT *
FROM Car_Option
INNER JOIN Option ON Option.OptionID = Car_Option.OptionID
WHERE CarID IN (
'80297476-f104-406e-bf2c-535042f2db4e',
'a6486941-57af-42f4-ae72-ef939581e209',
'etc...'
)