0

SQL Server Management Studio を介して実行している以下のクエリは、非常に遅いです。

入力テーブルtbl_sb12_bhsには約 40000 レコードがあり、1 時間後には 40 レコードのみが処理されます。

これを少し速く実行するには、ここで何を変更できますか?

DECLARE @bsrange INT

SET @bsrange = 0

WHILE @bsrange <= (SELECT max([p_a_l_out])
                   FROM   [DB001].[FD\f7].[tbl_sb12_bhs])
  BEGIN
      INSERT INTO [FD\f7].tbl_sb13_b_lin1
                  (aId,
                   p_a_l_out,
                   bs_id,
                   bs_db,
                   bs_tbl,
                   bs_column,
                   Int1,
                   cd1,
                   Hop1,
                   Int2,
                   cd2,
                   Hop2,
                   Int3,
                   cd3,
                   Hop3,
                   Int4,
                   cd4,
                   Hop4,
                   Int5,
                   cd5,
                   Hop5,
                   Int6,
                   cd6,
                   Hop6,
                   Int7,
                   cd7,
                   Hop7,
                   Int8,
                   cd8,
                   Hop8,
                   Int9,
                   cd9,
                   Hop9,
                   Int10,
                   cd10,
                   Hop10,
                   Int11,
                   cd11,
                   Hop11,
                   Int12,
                   cd12,
                   Hop12,
                   Int13,
                   cd13,
                   Hop13,
                   Int14,
                   cd14,
                   Hop14,
                   Int15,
                   cd15,
                   Hop15,
                   Int16,
                   cd16,
                   Hop16)
      SELECT DISTINCT tbl_sb12_bhs.aId,
                      tbl_sb12_bhs.p_a_l_out,
                      tbl_sb12_bhs.bs_id,
                      tbl_sb12_bhs.bs_db,
                      tbl_sb12_bhs.bs_tbl,
                      tbl_sb12_bhs.bs_column,
                      tbl_rpt_val_pt_crl.pt_el_Int    AS Int1,
                      tbl_rpt_val_pt_crl.user_cd      AS cd1,
                      tbl_rpt_val_pt_crl.cfk_upel     AS Hop1,
                      tbl_rpt_val_pt_crl_1.pt_el_Int  AS Int2,
                      tbl_rpt_val_pt_crl_1.user_cd    AS cd2,
                      tbl_rpt_val_pt_crl_1.cfk_upel   AS Hop2,
                      tbl_rpt_val_pt_crl_2.pt_el_Int  AS Int3,
                      tbl_rpt_val_pt_crl_2.user_cd    AS cd3,
                      tbl_rpt_val_pt_crl_2.cfk_upel   AS Hop3,
                      tbl_rpt_val_pt_crl_3.pt_el_Int  AS Int4,
                      tbl_rpt_val_pt_crl_3.user_cd    AS cd4,
                      tbl_rpt_val_pt_crl_3.cfk_upel   AS Hop4,
                      tbl_rpt_val_pt_crl_4.pt_el_Int  AS Int5,
                      tbl_rpt_val_pt_crl_4.user_cd    AS cd5,
                      tbl_rpt_val_pt_crl_4.cfk_upel   AS Hop5,
                      tbl_rpt_val_pt_crl_5.pt_el_Int  AS Int6,
                      tbl_rpt_val_pt_crl_5.user_cd    AS cd6,
                      tbl_rpt_val_pt_crl_5.cfk_upel   AS Hop6,
                      tbl_rpt_val_pt_crl_6.pt_el_Int  AS Int7,
                      tbl_rpt_val_pt_crl_6.user_cd    AS cd7,
                      tbl_rpt_val_pt_crl_6.cfk_upel   AS Hop7,
                      tbl_rpt_val_pt_crl_7.pt_el_Int  AS Int8,
                      tbl_rpt_val_pt_crl_7.user_cd    AS cd8,
                      tbl_rpt_val_pt_crl_7.cfk_upel   AS Hop8,
                      tbl_rpt_val_pt_crl_8.pt_el_Int  AS Int9,
                      tbl_rpt_val_pt_crl_8.user_cd    AS cd9,
                      tbl_rpt_val_pt_crl_8.cfk_upel   AS Hop9,
                      tbl_rpt_val_pt_crl_9.pt_el_Int  AS Int10,
                      tbl_rpt_val_pt_crl_9.user_cd    AS cd10,
                      tbl_rpt_val_pt_crl_9.cfk_upel   AS Hop10,
                      tbl_rpt_val_pt_crl_10.pt_el_Int AS Int11,
                      tbl_rpt_val_pt_crl_10.user_cd   AS cd11,
                      tbl_rpt_val_pt_crl_10.cfk_upel  AS Hop11,
                      tbl_rpt_val_pt_crl_11.pt_el_Int AS Int12,
                      tbl_rpt_val_pt_crl_11.user_cd   AS cd12,
                      tbl_rpt_val_pt_crl_11.cfk_upel  AS Hop12,
                      tbl_rpt_val_pt_crl_12.pt_el_Int AS Int13,
                      tbl_rpt_val_pt_crl_12.user_cd   AS cd13,
                      tbl_rpt_val_pt_crl_12.cfk_upel  AS Hop13,
                      tbl_rpt_val_pt_crl_13.pt_el_Int AS Int14,
                      tbl_rpt_val_pt_crl_13.user_cd   AS cd14,
                      tbl_rpt_val_pt_crl_13.cfk_upel  AS Hop14,
                      tbl_rpt_val_pt_crl_14.pt_el_Int AS Int15,
                      tbl_rpt_val_pt_crl_14.user_cd   AS cd15,
                      tbl_rpt_val_pt_crl_14.cfk_upel  AS Hop15,
                      tbl_rpt_val_pt_crl_15.pt_el_Int AS Int16,
                      tbl_rpt_val_pt_crl_15.user_cd   AS cd16,
                      tbl_rpt_val_pt_crl_15.cfk_upel  AS Hop16
      FROM   (SELECT DISTINCT pk_a AS aId,
                              p_a_l_out,
                              bs_id,
                              bs_db,
                              bs_tbl,
                              bs_column,
                              hop_pt_id_1,
                              hop_pt_id_2,
                              hop_pt_id_3,
                              hop_pt_id_4,
                              hop_pt_id_5,
                              hop_pt_id_6,
                              hop_pt_id_7,
                              hop_pt_id_8,
                              hop_pt_id_9,
                              hop_pt_id_10,
                              hop_pt_id_11,
                              hop_pt_id_12,
                              hop_pt_id_13,
                              hop_pt_id_14,
                              hop_pt_id_15,
                              hop_pt_id_16
              FROM   [FD\f7].tbl_sb12_bhs
              WHERE  [p_a_l_out] >= @bsrange
                     AND [p_a_l_out] < ( @bsrange + 1 )) AS tbl_sb12_bhs
             LEFT JOIN tbl_rpt_val_pt_crl
               ON tbl_sb12_bhs.hop_pt_id_1 = tbl_rpt_val_pt_crl.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_1
               ON tbl_sb12_bhs.hop_pt_id_2 = tbl_rpt_val_pt_crl_1.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_2
               ON tbl_sb12_bhs.hop_pt_id_3 = tbl_rpt_val_pt_crl_2.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_3
               ON tbl_sb12_bhs.hop_pt_id_4 = tbl_rpt_val_pt_crl_3.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_4
               ON tbl_sb12_bhs.hop_pt_id_5 = tbl_rpt_val_pt_crl_4.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_5
               ON tbl_sb12_bhs.hop_pt_id_6 = tbl_rpt_val_pt_crl_5.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_6
               ON tbl_sb12_bhs.hop_pt_id_7 = tbl_rpt_val_pt_crl_6.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_7
               ON tbl_sb12_bhs.hop_pt_id_8 = tbl_rpt_val_pt_crl_7.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_8
               ON tbl_sb12_bhs.hop_pt_id_9 = tbl_rpt_val_pt_crl_8.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_9
               ON tbl_sb12_bhs.hop_pt_id_10 = tbl_rpt_val_pt_crl_9.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_10
               ON tbl_sb12_bhs.hop_pt_id_11 = tbl_rpt_val_pt_crl_10.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_11
               ON tbl_sb12_bhs.hop_pt_id_12 = tbl_rpt_val_pt_crl_11.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_12
               ON tbl_sb12_bhs.hop_pt_id_13 = tbl_rpt_val_pt_crl_12.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_13
               ON tbl_sb12_bhs.hop_pt_id_14 = tbl_rpt_val_pt_crl_13.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_14
               ON tbl_sb12_bhs.hop_pt_id_15 = tbl_rpt_val_pt_crl_14.sk_el_pt
             LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_15
               ON tbl_sb12_bhs.hop_pt_id_16 = tbl_rpt_val_pt_crl_15.sk_el_pt

      SET @bsrange = @bsrange + 1
  END 
4

3 に答える 3

0

もう 1 つの方法は、最初に一時テーブルに結合してから、それを参照することです。毎回個別または結合を行う必要はありません。bsrange の where 句を追加するだけです。

したがって、次のようになります。

Create temporary table with as much of the joins/distinct as you can.
while.....
   insert into [FD\f7].tbl_sb13_b_lin1
       select * from temptable where  [p_a_l_out] >= @bsrange
                     AND [p_a_l_out] < ( @bsrange + 1 )
于 2013-05-02T12:22:15.393 に答える
0

私の最善の推測では、一度に多くの集中的な操作を行っているため、遅いと思います。サンプル データがないと難しいですが、いくつかの提案を試みることができます。

あなたが言ったことから、1 時間後に 40 レコードしか処理しないということから、速度を落としているのはループ内で起こっていることです。

SELECT DISTINCT は、すべてのデータを比較する必要があり、非常に多くの列を比較する必要があるため、安価ではありません。可能であれば、列の数を個別の選択に必要な最小限に制限し、それを元のテーブルに自己結合すると、実行が速くなる可能性があります。残りの部分とは別にテストして、同じ結果が得られていること、およびその方が速いかどうかを確認するのに十分なほど単純でなければなりません。

また、結合が多ければ多いほど、パフォーマンスは一般的に悪化します...正規化のために支払う代償です。

とにかく、私はそれから一歩下がって、これを最小の作業単位に分解しようとします。その後、犯人が見つかるまで、それぞれを個別にテストできます。そうすることで、これを行うためのより良い方法を考えるかもしれません。繰り返しますが、サンプル データがないと、これを支援するのは困難です。

于 2013-05-01T19:43:21.453 に答える
0

ターゲットに 1 つまたは複数のインデックスがある場合、SQL はすべての行のインデックスを再作成します。ターゲット テーブルのインデックスを無効にし、挿入が完了したら再度有効にします。(たとえば) 5k レコードの範囲内の挿入をバッチ処理して、ブロッキングが減少するようにするか、結果の選択と bcp の結果として一時ファイルを作成します。1 つのレコードを挿入する前に、その恐ろしい左結合のセットを毎回行うためです。SQL は、約 7 または 8 を超える左右の結合を最適化することはできません。私の推測では、挿入元のテーブルにはインデックスがほとんどまたはまったくないため、結合ごとにテーブル スキャンが実行されるか、挿入される 1 行ごとに約 17 個のテーブルがスキャンされます。申し訳ありませんが、このアプローチはすべての段階で間違っています。または、上司にデートセンターを買ってもらうこともできます....

于 2013-05-01T19:39:02.390 に答える