我正在使用Microsoft SQL Server2017。我有一个名为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)。
提前谢谢您。
已编辑
我只想知道是否删除所有上述索引(即[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
)
答案 0 :(得分: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
对于这四个索引,可以使用其中的一个 。当可以使用多个索引时,优化器将尝试使用“最佳”索引。有时,优化器没有选择最佳的。
问题的标题与聚集索引和非聚集索引有关。这带来了其他问题-尤其是如何插入和更新数据。聚簇索引对数据的存储方式施加了限制,因此它们可能对数据修改的性能产生重大影响。
索引还有更多细微差别。但是,从根本上说,它们不是由数据结构而是由查询驱动的(尽管在某些情况下,例如规范化数据模型,很明显,将需要某些类型的查询)。