2

CROSS JOIN2つのテーブルのMASSIVEを作成するプロセスを移植しています。結果のテーブルには15mのレコードが含まれます(プロセスが2600行のテーブルと12000行のテーブルと30mのクロス結合を行い、グループ化を行って半分に分割する必要があるようです)。行は比較的狭く、6列だけです。それは完了の兆候なしで5時間実行されています。既知のグッドとクロスジョインに期待するものとの間のカウントの不一致に気付いただけなので、出力にはファイナルテーブルを半分にするグループ化または重複排除がありません-しかし、これはまだ完了しないようですすぐに時間。

最初に、可能な限りこのテーブルをプロセスから削除することを検討します。明らかに、両方のテーブルを個別に結合することで置き換えることができますが、現在、使用されている他のすべての場所を把握することはできません。

しかし、既存のプロセスがそれを実行することを考えると(FOCUS言語を使用して、より短時間で、より強力でないマシンで)、CROSS JOINSQL Server(2005)の大容量のパフォーマンスを改善するためのオプションはありますか(ハードウェアは実際にはオプションではありません、このボックスは、32 GBのRAMを備えた64ビット8ウェイです)?

詳細:

これはFOCUSで次のように記述されています(同じ出力を生成しようとしています。これはSQLのCROSS JOINです)。

JOIN CLEAR *
DEFINE FILE COSTCENT
  WBLANK/A1 = ' ';
  END
TABLE FILE COSTCENT
  BY WBLANK BY CC_COSTCENT
  ON TABLE HOLD AS TEMPCC FORMAT FOCUS
  END

DEFINE FILE JOINGLAC
  WBLANK/A1 = ' ';
  END
TABLE FILE JOINGLAC
  BY WBLANK BY ACCOUNT_NO BY LI_LNTM
  ON TABLE HOLD AS TEMPAC FORMAT FOCUS INDEX WBLANK

JOIN CLEAR *
JOIN WBLANK IN TEMPCC TO ALL WBLANK IN TEMPAC
DEFINE FILE TEMPCC
  CA_JCCAC/A16=EDIT(CC_COSTCENT)|EDIT(ACCOUNT_NO);
  END
TABLE FILE TEMPCC
  BY CA_JCCAC BY CC_COSTCENT AS COST CENTER BY ACCOUNT_NO
  BY LI_LNTM
  ON TABLE HOLD AS TEMPCCAC
  END

したがって、必要な出力は実際にはCROSS JOINです(両側から空白の列を結合しています)。

SQLの場合:

CREATE TABLE [COSTCENT](
       [COST_CTR_NUM] [int] NOT NULL,
       [CC_CNM] [varchar](40) NULL,
       [CC_DEPT] [varchar](7) NULL,
       [CC_ALSRC] [varchar](6) NULL,
       [CC_HIER_CODE] [varchar](20) NULL,
 CONSTRAINT [PK_LOOKUP_GL_COST_CTR] PRIMARY KEY NONCLUSTERED
(
       [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY
= OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [JOINGLAC](
       [ACCOUNT_NO] [int] NULL,
       [LI_LNTM] [int] NULL,
       [PR_PRODUCT] [varchar](5) NULL,
       [PR_GROUP] [varchar](1) NULL,
       [AC_NAME_LONG] [varchar](40) NULL,
       [LI_NM_LONG] [varchar](30) NULL,
       [LI_INC] [int] NULL,
       [LI_MULT] [int] NULL,
       [LI_ANLZ] [int] NULL,
       [LI_TYPE] [varchar](2) NULL,
       [PR_SORT] [varchar](2) NULL,
       [PR_NM] [varchar](26) NULL,
       [PZ_SORT] [varchar](2) NULL,
       [PZNAME] [varchar](26) NULL,
       [WANLZ] [varchar](3) NULL,
       [OPMLNTM] [int] NULL,
       [PS_GROUP] [varchar](5) NULL,
       [PS_SORT] [varchar](2) NULL,
       [PS_NAME] [varchar](26) NULL,
       [PT_GROUP] [varchar](5) NULL,
       [PT_SORT] [varchar](2) NULL,
       [PT_NAME] [varchar](26) NULL
) ON [PRIMARY]

CREATE TABLE [JOINCCAC](
       [CA_JCCAC] [varchar](16) NOT NULL,
       [CA_COSTCENT] [int] NOT NULL,
       [CA_GLACCOUNT] [int] NOT NULL,
       [CA_LNTM] [int] NOT NULL,
       [CA_UNIT] [varchar](6) NOT NULL,
 CONSTRAINT [PK_JOINCCAC_KNOWN_GOOD] PRIMARY KEY CLUSTERED
(
       [CA_JCCAC] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY
= OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

SQLコードの場合:

INSERT  INTO [JOINCCAC]
       (
        [CA_JCCAC]
       ,[CA_COSTCENT]
       ,[CA_GLACCOUNT]
       ,[CA_LNTM]
       ,[CA_UNIT]
       )
       SELECT  Util.PADLEFT(CONVERT(varchar, CC.COST_CTR_NUM), '0',
                                     7)
               + Util.PADLEFT(CONVERT(varchar, GL.ACCOUNT_NO), '0',
                                       9) AS CC_JCCAC
              ,CC.COST_CTR_NUM AS CA_COSTCENT
              ,GL.ACCOUNT_NO % 900000000 AS CA_GLACCOUNT
              ,GL.LI_LNTM AS CA_LNTM
              ,udf_BUPDEF(GL.ACCOUNT_NO, CC.COST_CTR_NUM, GL.LI_LNTM, 'N') AS CA_UNIT
       FROM   JOINGLAC AS GL
       CROSS JOIN COSTCENT AS CC

このテーブルがその後どのように使用されるかに応じて、作成に使用された元のテーブルの両方に結合するだけで、プロセスから除外できるはずです。CROSS JOINただし、これは非常に大きな移植作業であり、しばらくの間テーブルの使用法が見つからない可能性があるため、そのような大きなテーブルをタイムリーに作成するためのトリックがあるかどうか疑問に思いました(特に既存のプロセスを考えると) FOCUSではよりスピーディーにそれを行うことができます)。そうすれば、置換クエリの構築の正しさを検証し、後でビューなどでそれを除外することができます。

また、UDFと文字列操作を除外し、最初にCROSS JOINを実行して、プロセスを少し分割することも検討しています。

結果は非常に遠い:

UDFはパフォーマンスに大きく(マイナスに)貢献していることがわかります。しかし、15mの列の交差結合と30mの列の交差結合の間にも大きな違いがあるように見えます。私はSHOWPLANの権利(boo hoo)を持っていないので、インデックスを変更した後、使用しているプラ​​ンが良いか悪いかわかりません。まだリファクタリングはしていませんが、テーブル全体がまもなくなくなると予想しています。

4

3 に答える 3

2

他の人のことわざを続けると、selectで使用されるクエリを含むDB関数は、常に私のクエリを非常に遅くしました。頭から離れて、45秒でクエリを実行し、関数を削除したところ、結果は0秒だったと思います:)

したがって、udf_BUPDEFがクエリを実行していないことを確認してください。

于 2008-12-10T06:00:25.060 に答える
2

そのクエリを調べると、1 つのテーブルからは 1 つの列のみが使用され、もう 1 つのテーブルからは 2 つの列のみが使用されていることがわかります。使用される列の数が非常に少ないため、このクエリはインデックスをカバーすることで簡単に拡張できます。

CREATE INDEX COSTCENTCoverCross ON COSTCENT(COST_CTR_NUM)
CREATE INDEX JOINGLACCoverCross ON JOINGLAC(ACCOUNT_NO, LI_LNTM)

さらに最適化するための私の質問は次のとおりです。

クエリをクエリ アナライザーに入れ、[推定実行プランを表示] ボタンを押すと、実行される内容がグラフィカルに表示されます。

結合の種類: ネストされたループ結合が必要です。(他のオプションは、マージ結合とハッシュ結合です)。ネストされたループが表示された場合は、OK です。マージ結合またはハッシュ結合が表示された場合は、お知らせください。

テーブルにアクセスする順序: 一番上まで移動し、右にスクロールします。最初のステップは、テーブルにアクセスすることです。それはどのテーブルで、どの方法が使用されていますか (インデックス スキャン、クラスター化インデックス スキャン)? 他のテーブルにアクセスするために使用されるメソッドは何ですか?

並列処理: 計画のほぼすべてのアイコンに、並列処理が使用されていることを示すギザギザの小さな矢印が表示されます。これが表示されない場合は、大きな問題があります。

その udf_BUPDEF が気になります。追加のテーブルから読み取りますか? Util.PADLEFT はあまり関係ありませんが、それでも..それは何ですか? データベース オブジェクトでない場合は、代わりにこれを使用することを検討してください。

RIGHT('z00000000000000000000000000' + columnName, 7)

JOINCCAC にトリガーはありますか? インデックスはどうですか?このサイズの挿入では、そのテーブルのすべてのトリガーとインデックスを削除する必要があります。

于 2008-12-10T05:41:09.967 に答える
1

クエリを分解して単純なクロス結合にします。


   SELECT  CC.COST_CTR_NUM, GL.ACCOUNT_NO
              ,CC.COST_CTR_NUM AS CA_COSTCENT
              ,GL.ACCOUNT_NO AS CA_GLACCOUNT
              ,GL.LI_LNTM AS CA_LNTM
-- I don't know what is BUPDEF doing? but remove it from the query for time being
--              ,udf_BUPDEF(GL.ACCOUNT_NO, CC.COST_CTR_NUM, GL.LI_LNTM, 'N') AS CA_UNIT
       FROM   JOINGLAC AS GL
       CROSS JOIN COSTCENT AS CC

単純なクロス結合がどれほど優れているかがわかりますか? (関数が適用されていない場合)

于 2008-12-10T05:08:24.730 に答える