0

SQL Server 2005 データベースに 193,569,270 行のテーブルがあります。テーブルには、当社の Web サイトのユーザーによって実行されるアクティビティが格納されます。テーブルは次のように定義されます。

名前の                  データ型
ID int (ID) PK
ActivityTime 日時
PersonID int (FK である必要がありますが、そうではありません)
ActivityTypeID int (FK である必要がありますが、そうではありません)
データ1 varchar(50)
Data2 varchar(50)

次のインデックスがあります。

非クラスター化インデックス [_MS_Sys_3] を [dbo].[tblPersonActivity] ([PersonID] ASC) に作成します。
INCLUDE ([ID]、[ActivityTime]、[ActivityTypeID]、[Data1]、[Data2])
WITH (PAD_INDEX = オフ、STATISTICS_NORECOMPUTE = オフ、SORT_IN_TEMPDB = オフ、IGNORE_DUP_KEY = オフ、DROP_EXISTING = オフ、ONLINE = オフ、ALLOW_ROW_LOCKS = オン、ALLOW_PAGE_LOCKS = オン) オン [プライマリ]
行く

CREATE NONCLUSTERED INDEX [IX_Activity] ON [dbo].[tblPersonActivity] ([PersonID] ASC、[ActivityTypeID] ASC、ActivityTime] ASC)
WITH (PAD_INDEX = オフ、STATISTICS_NORECOMPUTE = オフ、SORT_IN_TEMPDB = オフ、IGNORE_DUP_KEY = オフ、DROP_EXISTING = オフ、ONLINE = オフ、ALLOW_ROW_LOCKS = オン、ALLOW_PAGE_LOCKS = オン、FILLFACTOR = 90) オン [プライマリ]
行く

非クラスター化インデックス [IX_tblPersonActivity_PersonArchive] を [dbo].[tblPersonActivity] ([ActivityTime] ASC) に作成します。
INCLUDE ([ID]、[PersonID]、[ActivityTypeID]、[Data1]、[Data2])
WITH (PAD_INDEX = オフ、STATISTICS_NORECOMPUTE = オフ、SORT_IN_TEMPDB = オフ、IGNORE_DUP_KEY = オフ、DROP_EXISTING = オフ、ONLINE = オフ、ALLOW_ROW_LOCKS = オン、ALLOW_PAGE_LOCKS = オン) オン [プライマリ]
行く

ALTER TABLE [dbo].[tblPersonActivity] ADD CONSTRAINT [PK_tblPersonActivity] クラスター化されたプライマリ キー ([ID] ASC)
WITH (PAD_INDEX = オフ、STATISTICS_NORECOMPUTE = オフ、SORT_IN_TEMPDB = オフ、IGNORE_DUP_KEY = オフ、オンライン = オフ、ALLOW_ROW_LOCKS = オン、ALLOW_PAGE_LOCKS = オン) オン [プライマリ]
行く

これは私が書いたクエリです:

@archiveDate日時を宣言する
@curDate日時を宣言する
@startDate 日時を宣言する
@curYear int を宣言
@preYear int を宣言します

set @curDate = getdate()
set @curYear = year(@curDate)
set @preYear = @curYear - 1
@archiveDate = @curDate を設定
set @startDate = cast(('1/1/' + cast(@preYear as varchar(4))) as datetime)

@InactivePersons テーブルを宣言する
    (PersonID int not null PRIMARY KEY)

@InactiveBuyers に挿入
    選択する
        b.個人ID
    から
        HBM.dbo.tblPersons b with (INDEX(IX_tblPersons_InactiveDate_PersonID), nolock)
    どこ
        b.InactiveDate が null ではない
        b.InactiveDate '1900/1/1'
        b.InactiveDate '12/31/1899'
        および b.InactiveDate = @StartDate

最後にクエリを実行したとき、それを殺す前に 1 日以上実行されました。私は何かを逃したのでしょうか、それとも単にそのような時間がかかるのでしょうか?

ご協力いただきありがとうございます。

ウェイン・E・フェファー

4

1 に答える 1

0

いいえ、データベースが適切にセットアップされ、インデックスが作成されていれば、それほど時間はかかりません。

まず、これらの FK を作成する必要があります。データの整合性を確保するためにそれらを持たないことの言い訳はありません. FK には独自のインデックスが必要です。

非アクティブな日付がテーブル構造にないようです。日付フィールドですか?そうでない場合、または暗黙の変換を行うのに時間を浪費している場合は、1 つにしてください。

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

この where 句全体が意味をなさない。@startdate に一致するレコードを探している場合、残りは必要ありません。

実行計画を調べて、これに時間がかかっている場所を確認してください。何かがテーブル スキャンを引き起こしています。

また、テーブル変数に多数のレコードが存在する場合は、一時テーブルの方が高速に実行される傾向があります。プロシージャの残りの部分でこのテーブルを使用して何をしているのかはわかりませんが、最も時間がかかるのはinsertステートメントですか、それとも他のことですか?

于 2011-03-29T14:30:51.810 に答える