聚簇索引与复合索引。哪一个更好?

问题描述 投票:0回答:1

我正在使用Microsoft SQL Server 2017.我有一个名为ProductMapping的表。下面是表格结构:

CREATE TABLE [dbo].[Accommodation_ProductMapping](
    [ProductMappingId] [uniqueidentifier] NOT NULL,
    [AccommodationId] [uniqueidentifier] NULL,
    [SupplierId] [uniqueidentifier] NULL,
    [SupplierId] [varchar](50) NULL,
    [SupplierName] [varchar](50) NULL,
    [SupplierProductReference] [nvarchar](255) NULL,
    [ProductName] [nvarchar](500) NULL,
    [CountryName] [nvarchar](255) NULL,
    [CountryCode] [nvarchar](50) NULL,
    [CityName] [nvarchar](255) NULL,
    [CityCode] [nvarchar](100) NULL
)

该表有150亿个数据。我在这个表上创建了非集群和复合索引。以下是详细信息: -

CREATE NONCLUSTERED INDEX [IDX_CityCode] ON [dbo].[ProductMapping]
(
    [CityCode] ASC
)

CREATE NONCLUSTERED INDEX [IDX_CountryCode] ON [dbo].[ProductMapping]
(
    [CountryCode] ASC,
)

CREATE NONCLUSTERED INDEX [IDX_CountryCityCode] ON [dbo].[ProductMapping]
(
    [CountryCode] ASC,
    [CityCode] ASC
)

CREATE NONCLUSTERED INDEX [IDX_ProductCountryCityCode] ON [dbo].[ProductMapping]
(
    [ProductName] ASC,
    [CountryCode] ASC,
    [CityCode] ASC
)

CREATE NONCLUSTERED INDEX [IDX_AccommodationCountryCityCode] ON [dbo].[ProductMapping]
(
    [AccommodationId] ASC,
    [CountryCode] ASC,
    [CityCode] ASC
)

我能够毫无问题地获取数据。

我只是想知道上面创建的是否有任何未使用或冗余的索引?

我还在国家和城市代码上创建了一个复合索引“IDX_CountryCityCode”,因此我需要“CityCode”和“CountryCode”的单独非群集索引(例如IDX_CityCode和IDX_CountryCode)。

提前谢谢你。

EDITED

我只想知道是否删除了所有上述索引(即[IDX_CityCode],[IDX_CountryCode],[IDX_CountryCityCode],[IDX_ProductCountryCityCode]和[IDX_AccommodationCountryCityCode])并将它们全部放在一个复合索引中,如下所示。这会起作用还是最好的方法?

CREATE NONCLUSTERED INDEX [IDX_CityCountryAccommodationProduct] ON [dbo].[ProductMapping]
(
    [CityCode] ASC,
    [CountryCode] ASC,
    [AccommodationId] ASC,
    [ProductName] ASC
)
sql sql-server sqlperformance clustered-index non-clustered-index
1个回答
0
投票

你的问题很广泛。这个答案的目的是让你了解你提出的问题,因为这个问题似乎并不广泛 - 只是两个不同选项之间的二元选择。

创建索引以优化查询(以及强制执行唯一约束,但这是另一回事)。

您没有显示任何查询,因此无法确定哪组索引是最佳的。但是,它们并不等同。

您的复合索引可用于以下where子句:

where CityCode = @CityCode
where CityCode = @CityCode and CountryCode = @CountryCode
where CityCode = @CityCode and CountryCode = @CountryCode and AccommodationId = @AccommodationId
where CityCode = @CityCode and CountryCode = @CountryCode and AccommodationId = @AccommodationId and ProductName = @ProductName

重要的是列按索引中定义的顺序使用(而不是它们在where子句中显示的顺序。

如果不存在@CityId,则不能使用此索引。因此,该指数不适合:

where CountryCode = @CountryCode
where CountryCode = @CountryCode and AccommodationId = @AccommodationId
whereCountryCode = @CountryCode and AccommodationId = @AccommodationId and ProductName = @ProductName

使用这四个索引,可以使用其中一个。当可以使用多个索引时,优化器会尝试使用“最佳”索引。有时,优化器不会选择最佳的优化器。

您的问题的标题是关于聚簇索引和非聚簇索引。这带来了其他问题 - 特别是如何插入和更新数据。聚簇索引对数据的存储方式施加了限制,因此它们可以对数据修改的性能产生重大影响。

索引还有很多细微差别。但是,从根本上说,它们不是由数据结构驱动,而是由查询驱动(尽管在某些情况下,例如规范化数据模型,显然需要某些类型的查询)。

© www.soinside.com 2019 - 2024. All rights reserved.