2

我有一个包含几列的表,其中两个重要的是 appid 和 fileid。他们一起组成了桌子的PK。该表的一个典型用例是有多少文件包含 appid x,或者哪个 appid 最受欢迎。这些查询也将经常仅在文件的子集上运行,而不是在所有文件上运行。两列都不是唯一的。

基于此,我觉得聚集索引的最佳选择是 AppId。但是,由于将两列都设置为 PK 会产生额外的非聚集索引,并且 appid 缺乏唯一性(会有很多重复)意味着无论如何它都需要一个 uniquifier 列,所以只说PK 是聚集的而不是指定另一个聚集索引?假设我首先在 PK 中指定 AppId,它是否会将 diagnosticfileid 视为幕后的唯一性并以这种方式为我提供最佳性能?

编辑:我最初忘记提到的一件重要的事情是 APPId 不会稳步增加或任何东西,因此表格中间会有插入。我在想我可以通过使用填充因子来防止一些问题,但是表格会变得很大,所以我不知道这会有多大帮助。

此外,它会经常插入,但不会一次插入大块。可能是每小时几千行。确实没有任何价值可以可靠地增加并且在这方面对于聚集索引来说是一个不错的选择,但我不确定这有多大的意义。我可以添加一个 id 只是为了具有良好的集群价值,但我觉得这会减慢选择速度。

4

2 回答 2

3

如果您的两个最受欢迎的查询是“有多少文件包含appId”和“哪个appId最受欢迎”,您应该制作这个索引视图:

CREATE VIEW
        v_appCount
WITH SCHEMABINDING
AS
        SELECT  appId, COUNT_BIG(*) AS cnt
        FROM    dbo.mytable
        GROUP BY
                appId
GO

CREATE UNIQUE CLUSTERED INDEX
        ux_v_appCount_appId
ON      v_appCount (appId)

这样您就可以运行这些查询:

SELECT  cnt
FROM    v_appCount
WHERE   appId = @myAppId

SELECT  TOP 100
        *
FROM    v_appCount va
ORDER BY
        appId DESC

几乎是瞬间。

于 2013-04-17T22:25:01.177 回答
1

如果复合 PK 是集群的,就会出现问题,因为表中间的插入会导致内容的物理重新排序。如果桌子预计不会达到巨大的尺寸,那么这可能无关紧要,但这绝对是需要考虑的事情。我应该补充一点,如果这是一个高选择表和一个低插入表,那么这也限制了主键中间插入的影响。您绝对可以将其设为非聚集主键,但这有一些性能方面的考虑。

编辑
考虑到您的编辑,我建议您执行自动递增 PK(即非聚集)并创建唯一约束(也创建唯一的非聚集索引)。基本上,我不建议在此表上使用聚集索引。我认为没有它你不会看到太大的性能差异,但如果它在那里并且你在表格中间做了数千次插入,你会看到。死锁会困扰你。

快速阅读这篇文章。虽然它很旧,但原则仍然适用。

于 2013-04-17T21:36:05.577 回答