我有一個關於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