集群与非集群供参考 table

Clustered vs Nonclustered for a Reference table

我有一个简单的产品 table 可以跟踪产品数据。大多数时候我不需要知道它是什么类型的产品,但偶尔我需要知道产品类型。现在,由于并非所有产品都有类型(这会导致大量 NULL 行),因此当我需要该信息时,我使用引用 table 来加入产品类型。参考 table 使用复合键,我想弄清楚的是主键应该是聚簇索引还是非聚簇索引。产品 table 的主键有一个聚簇索引,所以我想知道如果它也是一个聚簇索引(以便 id 的顺序是有序的),连接是否会更有效率。还是在连接期间忽略了这一点,因此非集群会更有效率,因为它不进行键查找?

CREATE TABLE [dbo].[sales_product_type]
(
    [FK_product_id] [int] NOT NULL,
    [product_type] [int] NOT NULL,
    [type_description] [nvarchar](max) NULL,

    CONSTRAINT [PK_sales_product_type] 
        PRIMARY KEY CLUSTERED ([FK_product_id] ASC, [product_type] 
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[sales_product]
(
    [product_id] [int] IDENTITY(1,1) NOT NULL,
    [FK_store_id] [int] NOT NULL,
    [price] [int] NOT NULL,
    [product_name] [nvarchar](max) NOT NULL,
    [units] [int] NULL,

    CONSTRAINT [PK_sales_product] 
        PRIMARY KEY CLUSTERED ([product_id] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

如果在查询产品类型时需要[type_description]列,则应使用聚簇索引。原因是聚簇索引将包含 table 的所有列(包括键列 Product ID 和 Product Type)。

另一方面,如果您在产品 ID 和产品类型上只有 non-clustered 索引,当您的查询需要获取 type_description 时,它必须为每个索引执行堆查找输入结果数据集。

因此,如果您需要 type_description 在结果中,您 应该 保留聚集索引。


但是,在您的特定情况下,type_description 是否大于 8000 个字符并不重要。如前所述 here (and here),如果列的值超过 8000 个字符,则该列的值将被存储 out-of-row。所以在任何情况下,引擎都必须执行查找才能获得该值。


如果您不打算经常查询 type_description,使用 non-clustered 索引可能会导致读取次数低得多 - 因为引擎不必遍历 type_description 场地。但我会先测试这两种方法,然后再决定采用哪种方法。

一般来说,我总是在 table 上有一个聚簇索引。如果需要,我可能会添加一个 non-clustered 索引来调整特定查询。