My goal is to design a table, that can be queried trough an external id(uniqueidentifier
), an internal id(bigint
), always in combination with companyId(bigint)
, userId(bigint)
and dashboardId(bigint)
or in combination with (dashboardId IN @0, ..., @n
, n=0,10), both of which conditions play the role of an ownership check.
I came up with the following index compositions:
CREATE CLUSTERED INDEX Mytable_createdBy_cix ON Mytable(companyId, createdBy, dashboardId)
CREATE UNIQUE NONCLUSTERED INDEX Mytable_extId_nix ON Mytable(extId) INCLUDE (valueD, valueN)
CREATE UNIQUE NONCLUSTERED INDEX Mytable_chartId_nix ON Mytable (chartId) INCLUDE (valueD, valueN)
I do not know the answer of the following questions:
- Is the clustered index bad due to being non-unique? Should I add segregate key and not use the auto-assigned
uniqueifier
? - Are 3 * 8-byte columns + 4 byte uniqueifier(28bytes total) too much for a clustered index? I read it gets included in the include pages of each unique nonclustered index (where additional 16 or 8 bytes are added according to the key used).
- Does this index design even make sense for the queries below?
I plan on running queries, similar to those:
SELECT chartId, valueD, valueN FROM Mytable WHERE companyId = @companyId AND createdBy = @userId
SELECT chartId, valueD, valueN FROM Mytable WHERE companyId = @companyId AND createdBy = @userId AND dashboardId = @dashboardId
SELECT chartId, valueD, valueN FROM Mytable WHERE dashboardId IN (@0, @1, @2)
SELECT chartId, valueD, valueN FROM Mytable WHERE (companyId = @companyId AND createdBy = @userId AND dashboardId = @dashboardId) OR dashboardId IN (@0, @1, @2)
UPDATE Mytable SET valueD = @valueD WHERE companyId = @companyId AND createdBy = @userId AND chartId = @chartId
UPDATE Mytable SET valueD = @valueD WHERE companyId = @companyId AND createdBy = @userId AND extChartId= @extId
UPDATE Mytable SET valueD = @valueD WHERE ((companyId = @companyId AND createdBy = @userId) OR dashboardId IN (@0, @1, @2)) AND extChartId= @extId
I do know, it is better to test, evaluate execution plans, share them when asking questions on stackexchange, but this is the design phase so no actual data or tables exist yet.
I can adjust the keys/indexes/table structure to better fit the queries. I just hope to get it at least partially right this first time while creating them, so the question does not get revisited.
Big thanks for any help in advance.
extId
come in, is that a typo forextChartId
? And why two unique non-clustered indexes, how does that make sense?chartId
andextChartId
guaranteed unique columns?Charts
. In a previous iteration, we had one only one surrogate key in this table, but then thought it will be better to take the speed of havingint
keys for internal queries, and expose theuniqueidentifier
to the userscompanyId = @companyId AND createdBy = @userId AND chartId = @chartId
ifchartId
is already unique? Also, unlikely another whole surrogate key will make things much faster