0

我在 SQL Server 2005 数据库中有一个包含 193,569,270 行的表。该表包含我们网站用户执行的活动。该表定义为:

名称                  数据类型
ID int(身份)PK
活动时间日期时间
PersonID int(应该是 FK,但不是)
ActivityTypeID int(应该是 FK,但不是)
数据1 varchar(50)
数据2 varchar(50)

我有以下索引:

在 [dbo].[tblPersonActivity] ([PersonID] ASC) 上创建非集群索引 [_MS_Sys_3]
包括([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 [主要]
去

在 [dbo].[tblPersonActivity] 上创建非聚集索引 [IX_Activity]([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 [主要]
去

创建非集群索引 [IX_tblPersonActivity_PersonArchive] ON [dbo].[tblPersonActivity] ([ActivityTime] ASC)
包括([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 [主要]
去

ALTER TABLE [dbo].[tblPersonActivity] 添加约束 [PK_tblPersonActivity] 主键集群([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]
去

这是我写的查询:

声明 @archiveDate 日期时间
声明@curDate 日期时间
声明 @startDate 日期时间
声明@curYear int
声明@preYear int

设置@curDate = getdate()
设置@curYear = 年(@curDate)
设置@preYear = @curYear - 1
设置@archiveDate = @curDate
将@startDate = cast(('1/1/' + cast(@preYear as varchar(4))) 设置为日期时间)

声明@InactivePersons 表
    (PersonID int 不为空主键)

插入@InactiveBuyers
    选择
        b.人名
    从
        HBM.dbo.tblPersons b with (INDEX(IX_tblPersons_InactiveDate_PersonID), nolock)
    在哪里
        b.InactiveDate 不为空
        和 b.InactiveDate '1/1/1900'
        和 b.InactiveDate '12/31/1899'
        和 b.InactiveDate = @StartDate

上次我运行查询时,它运行了超过 1 天,然后才杀死它。我错过了什么或者这只是需要那种时间吗?

感谢您的任何帮助,您可以提供。

韦恩·E·普费弗

4

1 回答 1

0

不,如果您的数据库正确设置和索引,这应该不会花费那么长时间。

首先,您需要创建那些 FK!没有理由不让它们确保您的数据完整性。FK 应该有自己的索引。

非活动日期似乎不在您的表结构中。它是一个日期字段吗?如果不是,则将其设为一个,或者您正在浪费时间进行隐式转换。

b.InactiveDate is not null 
        and b.InactiveDate  '1/1/1900' 
        and b.InactiveDate  '12/31/1899' 
        and b.InactiveDate = @StartDate

这整个 where 子句没有意义。如果您正在寻找与 @startdate 匹配的记录,那么您不需要任何其他记录。

查看执行计划,看看这花了这么长时间,是什么导致了表扫描。

如果表变量中有大量记录,那么临时表往往会执行得更快。您没有在 proc 的其余部分中说明您在使用此表做什么,您确定它是插入语句花费的时间最多还是您正在做的其他事情?

于 2011-03-29T14:30:51.810 回答