2011-03-29 31 views
0

我有一個在SQL Server 2005數據庫中有193,569,270行的表。該表包含我們網站用戶執行的活動。該表定義爲:從sql server 2005中有大約2億行的表中進行選擇時,select into query需要多長時間?

 
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 

我最後一次運行查詢它跑了一天後才殺死它。我錯過了什麼,或者這只是要採取那種時間?

感謝您提供的任何幫助。

韋恩E.普費弗

回答

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的記錄,那麼您不需要其他任何記錄。

查看執行計劃,看看這些花費的時間如此之長,導致表掃描。

如果在表中會有大量記錄變化,那麼臨時表往往會執行得更快。你不會說在處理其餘部分的表中你正在做什麼,你確定它是插入語句花費最多時間還是你正在做的其他事情?

相關問題