我的目标是设计一个表,可以通过外部 id( uniqueidentifier
)、内部 id( bigint
) 进行查询,始终与和/或与 ( , n=0,10) 结合使用companyId(bigint)
,这两个条件都起到所有权检查的作用。userId(bigint)
dashboardId(bigint)
dashboardId IN @0, ..., @n
我想出了以下指数组成:
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)
我不知道以下问题的答案:
- 聚集索引是否因为非唯一而坏?我应该添加隔离键而不使用自动分配的
uniqueifier
吗? - 3 * 8 字节列 + 4 字节唯一符(总共 28 字节)对于聚集索引来说太多了吗?我读到它包含在每个唯一非聚集索引的包含页面中(根据使用的键添加额外的 16 或 8 个字节)。
- 这种索引设计对下面的查询是否有意义?
我计划运行查询,类似于:
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
我确实知道,最好在 stackexchange 上提问时测试、评估执行计划并分享它们,但这是设计阶段,因此还没有实际的数据或表格。
我可以调整键/索引/表结构以更好地适应查询。我只是希望在第一次创建它们时至少部分正确,所以这个问题不会被重新讨论。
非常感谢您提前提供的任何帮助。