我正在使用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
)
你的问题很广泛。这个答案的目的是让你了解你提出的问题,因为这个问题似乎并不广泛 - 只是两个不同选项之间的二元选择。
创建索引以优化查询(以及强制执行唯一约束,但这是另一回事)。
您没有显示任何查询,因此无法确定哪组索引是最佳的。但是,它们并不等同。
您的复合索引可用于以下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
使用这四个索引,可以使用其中一个。当可以使用多个索引时,优化器会尝试使用“最佳”索引。有时,优化器不会选择最佳的优化器。
您的问题的标题是关于聚簇索引和非聚簇索引。这带来了其他问题 - 特别是如何插入和更新数据。聚簇索引对数据的存储方式施加了限制,因此它们可以对数据修改的性能产生重大影响。
索引还有很多细微差别。但是,从根本上说,它们不是由数据结构驱动,而是由查询驱动(尽管在某些情况下,例如规范化数据模型,显然需要某些类型的查询)。