2016-12-01 18 views
2

I 5万件のレコードが含まれている私のDB内のテーブルがあります:あなたは、上から見ることができるようにパフォーマンスを最適化 - インデックス

CREATE TABLE [dbo].[PurchaseFact](
    [Branch] [int] NOT NULL, 
    [ProdAnal] [varchar](30) NULL, 
    [Account] [varchar](12) NULL, 
    [Partno] [varchar](24) NULL, 
    [DteGRN] [date] NULL, 
    [DteAct] [date] NULL, 
    [DteExpect] [date] NULL, 
    [OrderNo] [bigint] NULL, 
    [GRNNO] [varchar](75) NULL, 
    [SuppAdv] [varchar](75) NULL, 
    [Supplier] [varchar](12) NULL, 
    [OrdType] [varchar](4) NULL, 
    [UnitStock] [varchar](4) NULL, 
    [OrderQty] [float] NULL, 
    [RecdQty] [float] NULL, 
    [Batch] [varchar](100) NULL, 
    [CostPr] [float] NULL, 
    [Reason] [varchar](2) NULL, 
    [TotalCost] [float] NULL, 
    [Magic] [bigint] IDENTITY(1,1) NOT NULL, 
PRIMARY KEY CLUSTERED 
(
    [Magic] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

を - CLUSTERED INDEXがあるMAGIC列で使用されていますUNIQUEカラム。

SELECT Branch, 
    Supplier, 
    ProdAnal, 
    DteGRN AS Date, 
    PartNo AS Partno, 
    OrderNo, 
    OrderQty, 
    TotalCost, 
    CostPr 
FROM dbo.PurchaseFact src 
WHERE YEAR(DteGRN) = 2016 

WHERE clauseも問合せが速く実行させない除く:以下SELECT statementため

データ検索時間は十分に問題を報告する原因となる8minsの上にあります。 私はそれが高速に実行することを期待したが無駄にUNIQUE indexを含めるために一緒にCLUSTERED indexで、試してみました:

CREATE UNIQUE INDEX Unique_Index ON dbo.PurchaseFact ([Branch], [Supplier], [Magic]) 
INCLUDE ([ProdAnal], [Account], [Partno], [DteAct], [DteExpect], [OrderNo], [GRNNO], 
[SuppAdv], [OrdType], [UnitStock]) 

は、私は、このテーブルの上にパフォーマンス時間を最適化することができますか私はに頼る必要がありますどのような方法があります古いデータをアーカイブしますか?

アドバイスをいただければ幸いです。

+0

2016年に返される行数はいくつですか?データ転送には時間がかかることがあります。 – jarlh

+1

その年計算を行うために永続計算列を追加できますか?このフィールドにクラスタ化されていないインデックスを追加し、他のインデックスを含めることができます。 –

+0

@ jarlh - 1,600万レコードが返されます。 – PKirby

答えて

4

これはあなたのwhere句です:

WHERE YEAR(DteGRN) = 2016 

表5万行を持っている場合は、この日付のいずれかの合理的な分布を仮定し、大量のデータを返すために起こっています。おそらく、データの量はクエリの時間の長さに関係しています。あなたが行うことができます

ことの一つは、WHEREを修正してくださいし、適切な列にインデックスを置くことです:

WHERE DteGRN >= '2016-01-01' and DteGRN < '2017-01-01' 

これは、その後PurchaseFact(DteGRN)にインデックスを利用することができます。しかし、返される可能性のある行数を考えると、おそらくインデックスはあまり役に立ちません。

大きな問題は、レポートアプリケーションがデータベース内で要約するのではなく、2016年からすべての行を戻す理由です。私は、あなたは、レポートアプリケーションのアーキテクチャの問題があると思う。

+1

ありがとうゴードン - これは事をスピードアップする最も確かに助けになりました。 8分44秒から2分50分。 – PKirby

0

申し訳ありません、コメントを追加できません。

パフォーマンスをさらに向上させるには(UPDATEオーバーヘッドで使用できる場合)、クエリのSELECT部分​​の列のみを含むCOVERING INDEXを作成します。

0

申し訳ありませんが、フォーマットのために - 私は携帯電話でそれをやっている:

作成し、非クラスタ化インデックスIX_YourName ON dbo.PruchaseFact(DateGRN)は、(あなたが選択したが、ソートいけないすべての列):

はこれを試してみてください;

WHEREステートメントでは、どの関数も使用しないでください。これを使用すると、エンジンはENTIRE列を読み取り、すべての単一行でその関数を適用します。間に(上記のように)あなたの範囲のための適切なインデックス統計とバケットを(少なくともこの場合は値の年のように)作成するエンジンを少なくとも使用します。

関連する問題