首页 文章

从sql server 2005中的约2亿行的表中选择时,选择查询需要多长时间?

提问于
浏览
0

我在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 回答

  • 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的其余部分说出你在使用这个表做什么,你确定它是插入语句花费最多的时间或你正在做的其他事情吗?

相关问题