我在SQL Server 2005数据库中有一个包含193,569,270行的表 . 该表包含由我们网站的用户执行的活动 . 该表定义为:
Name DataType
ID int (identity) PK
ActivityTime datetime
PersonID int (should be an FK, but isn't)
ActivityTypeID int (should be an FK, but isn't)
Data1 varchar(50)
Data2 varchar(50)
我有以下索引:
CREATE NONCLUSTERED INDEX [_MS_Sys_3] ON [dbo].[tblPersonActivity] ([PersonID] ASC)
INCLUDE ( [ID], [ActivityTime], [ActivityTypeID], [Data1], [Data2])
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) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_Activity] ON [dbo].[tblPersonActivity] ([PersonID] ASC, [ActivityTypeID] ASC, ActivityTime] ASC)
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
CREATE NONCLUSTERED INDEX [IX_tblPersonActivity_PersonArchive] ON [dbo].[tblPersonActivity] ([ActivityTime] ASC)
INCLUDE ([ID], [PersonID], [ActivityTypeID], [Data1], [Data2])
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) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tblPersonActivity] ADD CONSTRAINT [PK_tblPersonActivity] PRIMARY KEY CLUSTERED ([ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
这是我写的查询:
declare @archiveDate datetime
declare @curDate datetime
declare @startDate datetime
declare @curYear int
declare @preYear int
set @curDate = getdate()
set @curYear = year(@curDate)
set @preYear = @curYear - 1
set @archiveDate = @curDate
set @startDate = cast(('1/1/' + cast(@preYear as varchar(4))) as datetime)
declare @InactivePersons table
(PersonID int not null PRIMARY KEY)
insert into @InactiveBuyers
select
b.PersonID
from
HBM.dbo.tblPersons b with (INDEX(IX_tblPersons_InactiveDate_PersonID), nolock)
where
b.InactiveDate is not null
and b.InactiveDate '1/1/1900'
and b.InactiveDate '12/31/1899'
and b.InactiveDate = @StartDate
我最后一次运行查询时它运行了超过1天才杀死它 . 我错过了什么,或者这只是需要那种时间吗?
感谢您的任何帮助,您可以提供 .
Wayne E. Pfeffer
1 回答
如果您的数据库已正确设置和编制索引,则不应该花这么长时间 .
首先你需要创建那些FK!没有理由不让他们确保您的数据完整性 . FK应该有自己的索引 .
非活动日期似乎不在您的表结构中 . 这是日期字段吗?如果它不是,或者你在浪费时间进行隐式转换,请将其设为一个 .
这整个where子句没有意义 . 如果您正在寻找与@startdate匹配的记录,那么您不需要任何其他记录 .
查看执行计划,看看这需要多长时间,导致表扫描 .
如果表中的大量记录可变,那么临时表往往表现得更快 . 你没有在proc的其余部分说出你在使用这个表做什么,你确定它是插入语句花费最多的时间或你正在做的其他事情吗?