2012-02-09 4 views
2

OracleからSql Serverデータベースに大量のデータを毎日取得する古いSSISパッケージがあります。データは正規化されていないデータベースに挿入され、ストアドプロシージャを使用してそのデータを選択し、正規化されたデータベースに挿入します。 Oracleデータベースは過度に正規化されていたため、私が書いたクエリでは、必要なすべての列を取得するために12個の内部結合が行われました。もう一つの問題は、私が大量のデータを扱っていることです。私が選んだ1つのテーブルには1200万を超えるレコードがあります。私のクエリは次のとおりです。大量のデータの処理とSQL Server 2008の12個の内部結合によるクエリ

Declare @MewLive Table 
(

UPC_NUMBER VARCHAR(50), 
ITEM_NUMBER VARCHAR(50), 
STYLE_CODE VARCHAR(20), 
COLOR VARCHAR(8), 
SIZE VARCHAR(8), 
UPC_TYPE INT, 
LONG_DESC VARCHAR(120), 
LOCATION_CODE VARCHAR(20), 
TOTAL_ON_HAND_RETAIL NUMERIC(14,0), 
VENDOR_CODE VARCHAR(20), 
CURRENT_RETAIL NUMERIC(14,2) 


) 

INSERT INTO @MewLive(UPC_NUMBER,ITEM_NUMBER,STYLE_CODE,COLOR,[SIZE],UPC_TYPE,LONG_DESC,LOCATION_CODE,TOTAL_ON_HAND_RETAIL,VENDOR_CODE,CURRENT_RETAIL) 
SELECT  U.UPC_NUMBER, REPLACE(ST.STYLE_CODE, '.', '') 
         + '-' + SC.SHORT_DESC + '-' + REPLACE(SM.PRIM_SIZE_LABEL, '.', '') AS ItemNumber, 
         REPLACE(ST.STYLE_CODE, '.', '') AS Style_Code, SC.SHORT_DESC AS Color, 
         REPLACE(SM.PRIM_SIZE_LABEL, '.', '') AS Size, U.UPC_TYPE, ST.LONG_DESC, L.LOCATION_CODE, 
         IB.TOTAL_ON_HAND_RETAIL, V.VENDOR_CODE, SD.CURRENT_RETAIL 
FROM   MewLive.dbo.STYLE AS ST INNER JOIN 
         MewLive.dbo.SKU AS SK ON ST.STYLE_ID = SK.STYLE_ID INNER JOIN 
         MewLive.dbo.UPC AS U ON SK.SKU_ID = U.SKU_ID INNER JOIN 
         MewLive.dbo.IB_INVENTORY_TOTAL AS IB ON SK.SKU_ID = IB.SKU_ID INNER JOIN 
         MewLive.dbo.LOCATION AS L ON IB.LOCATION_ID = L.LOCATION_ID INNER JOIN 
         MewLive.dbo.STYLE_COLOR AS SC ON ST.STYLE_ID = SC.STYLE_ID INNER JOIN 
         MewLive.dbo.COLOR AS C ON SC.COLOR_ID = C.COLOR_ID INNER JOIN 
         MewLive.dbo.STYLE_SIZE AS SS ON ST.STYLE_ID = SS.STYLE_ID INNER JOIN 
         MewLive.dbo.SIZE_MASTER AS SM ON SS.SIZE_MASTER_ID = SM.SIZE_MASTER_ID INNER JOIN 
         MewLive.dbo.STYLE_VENDOR AS SV ON ST.STYLE_ID = SV.STYLE_ID INNER JOIN 
         MewLive.dbo.VENDOR AS V ON SV.VENDOR_ID = V.VENDOR_ID INNER JOIN 
         MewLive.dbo.STYLE_DETAIL AS SD ON ST.STYLE_ID = SD.STYLE_ID 
WHERE  (U.UPC_TYPE = 1) AND (ST.ACTIVE_FLAG = 1) 

このクエリは、私たちのサーバーをかなりクラッシュさせます。クエリを小さなクエリに分割して問題を解決しようとしましたが、私が使用する一時テーブルの変数によって、tempdbデータベースがハードドライブを満たすことになります。これは、サーバーのメモリが不足してクラッシュするためです。とにかくこの問題を解決するには?

答えて

1

適切なインデックスは間違いなくこのクエリではない行の「無数」上の行の

IF

量を助けます。

次のことを試してみてください。dbo.STYLE_COLOR上のFKey(COLOR_ID)=> dbo.COLOR(COLOR_ID)

適切な指標(過度がある場合

  • dbo.COLORに参加が過剰です、見直されるべきである)SELECTリストで

    USE MewLive 
    CREATE INDEX ix1 ON dbo.STYLE_DETAIL (STYLE_ID) 
    INCLUDE (STYLE_CODE, LONG_DESC) 
    WHERE ACTIVE_FLAG = 1 
    GO 
    CREATE INDEX ix2 ON dbo.UPC (SKU_ID) 
    INCLUDE(UPC_NUMBER) 
    WHERE UPC_TYPE = 1 
    GO 
    CREATE INDEX ix3 ON dbo.SKU(STYLE_ID) 
    INCLUDE(SKU_ID) 
    GO 
    CREATE INDEX ix3_alternative ON dbo.SKU(SKU_ID) 
    INCLUDE(STYLE_ID) 
    GO 
    CREATE INDEX ix4 ON dbo.IB_INVENTORY_TOTAL(SKU_ID, LOCATION_ID) 
    INCLUDE(TOTAL_ON_HAND_RETAIL) 
    GO 
    CREATE INDEX ix5 ON dbo.LOCATION(LOCATION_ID) 
    INCLUDE(LOCATION_CODE) 
    GO 
    CREATE INDEX ix6 ON dbo.STYLE_COLOR(STYLE_ID) 
    INCLUDE(SHORT_DESC,COLOR_ID) 
    GO 
    CREATE INDEX ix7 ON dbo.COLOR(COLOR_ID) 
    GO 
    CREATE INDEX ON dbo.STYLE_SIZE(STYLE_ID) 
    INCLUDE(SIZE_MASTER_ID) 
    GO 
    CREATE INDEX ix8 ON dbo.SIZE_MASTER(SIZE_MASTER_ID) 
    INCLUDE(PRIM_SIZE_LABEL) 
    GO 
    CREATE INDEX ix9 ON dbo.STYLE_VENDOR(STYLE_ID) 
    INCLUDE(VENDOR_ID) 
    GO 
    CREATE INDEX ixA ON dbo.VENDOR(VENDOR_ID) 
    INCLUDE(VENDOR_CODE) 
    GO 
    CREATE INDEX ON dbo.STYLE_DETAIL(STYLE_ID) 
    INCLUDE(CURRENT_RETAIL) 
    

    1 as UPC_TYPE,

    U.UPC_TYPE,を交換
+0

列に1つのインデックス?一部の列には、主キーまたは古い索引がすでに設定されています。 – broke

+0

@broke yepこれは許可されており、これらのインデックスはクラスタ化されたものよりも優れています –

1

SKU/location/vendor/whateverによってインポートを分離し、複数のクエリを実行してデータを取得できますか?それはすべて1ヒットで横断する必要がある特定の理由はありますか? (クエリの書き易さは別として)

+0

テーブル構造は2 SQLデータベース間で全く異なっています – broke

4

一時テーブルの代わりに実テーブルを使用しようとしましたか? SELECT INTOを使用して、一時テーブルの代わりに結果を格納する実テーブルを作成できます。

構文は次のようになります。

SELECT 
    U.UPC_NUMBER, 
    REPLACE(ST.STYLE_CODE, '.', ''). 
    .... 
INTO 
    MEWLIVE 
FROM 
    MewLive.dbo.STYLE AS ST INNER JOIN 
    ... 

コマンドは、テーブルを作成し、あなたが見ているメモリの問題を助けることがあります。

さらに、クエリアナライザで実行計画を調べるか、インデックスチューニングウィザードを使用して、クエリの高速化に役立つインデックスを提案してみてください。

+0

良い提案ですが、私は実際のテーブルを使用することを考えませんでした。インデックスチューニングウィザードについては、どこで見つけることができますか? – broke

+0

-1表varsは、一時表と非常によく似ています。テンポラリテーブルの唯一の利点 - テンポラリテーブルにインデックスを個別に作成することができます。 –

+1

@OlegDokあなたが誤解したと思います。彼は実際のテーブルを提案しています。一時テーブル*または*テーブル変数ではありません。 tempdbがボトルネック(例えば、低速ディスク、すでに過負荷など)の場合、ユーザーデータベースに永続的なテーブルを作成することでメリットが得られます(より高速な記憶域にあるか圧倒される可能性があります)。 –

2

SQLサーバーからではなくOracleサーバーからクエリを実行してみてください。現状では、クエリが処理しようとしている間、多くの通信が行われます。

ジョインを前処理することによって(おそらくビューで)、結果だけを送信します。

オーバー正規化について:スピードの点で問題があるかどうかをテストしましたか?私はそれがでもであると信じるのは難しいと思う。

+0

LinkedServer機能を使用してSQL ServerをOracleサーバーに接続し、OPENQUERYメソッドを使用すると、Oracleデータベースのnad結果はSQLにパイプされます。 – Rikalous

関連する問題