我有一个关于SQL Server索引的问题。我不是DBA,并且假设对于那些你来说答案是清楚的。我使用SQL Server 2008的SQL Server索引顺序(日期时间字段)
我有一个表,它是类似于以下(但有更多列):
CREATE TABLE [dbo].[Results](
[ResultID] [int] IDENTITY(1,1) NOT NULL,
[TypeID] [int] NOT NULL,
[ItemID] [int] NOT NULL,
[QueryTime] [datetime] NOT NULL,
[ResultTypeID] [int] NOT NULL,
[QueryDay] AS (datepart(day,[querytime])) PERSISTED,
[QueryMonth] AS (datepart(month,[querytime])) PERSISTED,
[QueryYear] AS (datepart(year,[querytime])) PERSISTED,
CONSTRAINT [PK_Results] PRIMARY KEY CLUSTERED
(
[ResultID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
的重要领域这里需要注意的是ResultID,主键,和QueryTime结果产生的日期时间。
我也有以下指标(其中包括):
:CREATE NONCLUSTERED INDEX [IDX_ResultDate] ON [dbo].[Results]
(
[QueryTime] ASC
)
INCLUDE ([ResultID],
[ItemID],
[TypeID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
在一个数据库,在那里我有表中的一百万行,做一个查询,例如,当使用索引
select top 1 * from results where querytime>'2009-05-01' order by ResultID asc
在同一个数据库的另一个实例中,有5千万行,SQL Server决定不使用索引,而是使用聚集索引扫描,结果是速度非常慢。 (速度取决于日期)。即使我使用查询提示来使其使用IDX_ResultDate,它仍然有点慢,它的时间花费了94%的时间由ResultID排序。我想通过创建一个带有ResultID和QueryTime的索引作为索引中的已排序列,我可以加快查询速度。
因此,我创建了以下内容:
CREATE NONCLUSTERED INDEX [IDX_ResultDate2] ON [dbo].[Results]
(
[QueryTime] ASC,
[ResultID] ASC
)
INCLUDE ([ItemID],
[TypeID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
GO
我认为它会首先使用排序QueryTime找到匹配的结果,这已经ResultID进行排序。然而,情况并非如此,因为这个指数并没有改变现有指标的表现。
我然后尝试了以下指标:
CREATE NONCLUSTERED INDEX [IDX_ResultDate3] ON [dbo].[Results]
(
[ResultID] ASC,
[QueryTime] ASC
)
INCLUDE ([ItemID],
[TypeID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
GO
这一个产生预期的结果。它似乎以不变的时间(几分之一秒)返回。
但是,我很疑惑为什么IDX_ResultDate3工作正常,而IDX_ResultDate2不工作。
我会假设在QueryTime的排序列表中进行二分搜索,然后在结果ID的子列表中查看第一个结果,这是获取结果的最快方法。 (因此,我最初的排序顺序)。
旁边的问题:我应该创建一个持续的列,其中的QueryTime和索引的日期部分,而不是(我已经有三个持久列,你可以看到上面)?
非常好的解释。我现在知道了。我会看看我是否可以重新设计应用程序以使用QueryTime排序。 – 2009-07-09 22:00:45