ファクトテーブルCardTransactionFactがあります
テーブル構造
_TABLE [dbo].[CardTransactionFact]
[CardTransactionID] [int] IDENTITY(1,1) NOT NULL,
[TransactionTerminalID] [int] NOT NULL,
[SourceAccountTypeID] [int] NULL,
[DestinationAccountTypeID] [int] NULL,
[RimNo] [varchar](15) NULL,
[CaptureCodeID] [int] NOT NULL,
[RoutingCodeID] [int] NOT NULL,
[ProcessingCodeID] [int] NOT NULL,
[ActionCodeID] [int] NOT NULL,
[NetworkCodeID] [int] NOT NULL,
[ProductCodeID] [int] NOT NULL,
[AcquiringCountryCodeID] [int] NOT NULL,
[IssuingCountryCodeID] [int] NOT NULL,
[TransactionCurrencyCodeID] [int] NOT NULL,
[AmountBD] [decimal](18, 3) NOT NULL,
[LocalCurrencyCodeID] [int] NOT NULL,
[CardIssuerBank] [int] NOT NULL,
[CardTypeID] [int] NOT NULL,
[SuspectTransactionFlag] [char](1) NOT NULL,
[ReversalTransactionFlag] [char](1) NOT NULL,
[LocalTransactionDateKey] [int] NOT NULL,
[LocalTransactionHourKey] [int] NOT NULL,
[BBKRole] [char](1) NOT NULL,
[AmountRangeKey] [int] NULL,
[CustomerKey] [int] NULL
_
サイズ:11GB行数:56,959,828
現在、このテーブルにアクセスすることは非常に困難になっています。単純なSelect count(*) from CardTransactionFact
の実行には数時間かかります。
表のほとんどの列は単なる整数であるため、インデックスを作成しませんでした。
このテーブルを改善し、このテーブルへのクエリの速度を上げるために私は何をすべきだと思いますか
ここでは多くの問題がありますが、ありがたいことに修正できることがたくさんあります。
問題:
修正:
11GBは6GBに収まりません、それは本当にとても簡単です。非常に大まかな見積もりでは、テーブルが約150万ページを占めることを示唆しています。100IOPSの場合、ディスクからの読み取りには約4時間かかります(最悪の場合、100%ランダム読み取り、先読みなしなど)。
クエリを置き換える
SELECT COUNT(*) FROM CardTransactionFact
以下で
SELECT Rows FROM SYS.PARTITIONS WHERE OBJECT_ID = OBJECT_NAME('CardTransactionFact')
絶対必要です Clustered Index
テーブルに。 DBCC CONTIGを実行して、ヒープテーブルのフラグメンテーションを確認します
Create Clustered INDEX IX_Column on TableName(COLUMNNAME)
テーブルで発生する問題は、断片化の問題です。 DELETES、INSERTS、UPDATESなどの実行されるアクティビティによっては、ヒープテーブルとクラスター化テーブルが断片化する可能性があります。これの多くは、アクティビティと、クラスタ化されたインデックスに使用されるキー値に依存します。
DBCC CONTIGを再度実行して、ヒープテーブルのフラグメンテーションを確認します
インデックスクエリを再構築してインデックスを削除します
ALTER INDEX ALL
ON TableName
REBUILD WITH
(
FILLFACTOR = 80,
SORT_IN_TEMPDB = ON,
STATISTICS_NORECOMPUTE = ON
);
インデックス作成とパーティショニングの両方が非常に役立ちます。ただし、どのインデックスとパーティションの分割方法は、それらに対して実行するクエリに大きく依存します。
インデックスやパーティショニングがない場合、クエリオプティマイザーはすべてのクエリの完全なテーブルを読み取る必要があります。
パーティショニング部分について、データを複数のパーティションに簡単に分離するために使用できる論理列はありますか?そして、この列をほとんどのクエリのwhere句に追加することは可能ですか?