0

私は2つのテーブルtab1tab2. tab1には 39000 件のレコードがあり、tab215000 件のレコードがあります。tab1両方ともtab2、 という 2 つの共通の列がitem_numberありcolor_codeます。しかし、 intab1color_codenull かもしれませんが、 in ではありませんtab2item_number両方のテーブルで null ではありません。から行 ( 2tab2つの列に基づく一意の行) データを挿入する必要がありますtab1。このために、私はこのような手順を書きました。各行を比較しますが、時間がかかりすぎます。パフォーマンスを向上させる方法はありますか。最初に 2 つのカーソルを取得します。

CURSOR CUR_tab1 IS SELECT item_number,color_code FROM 
    (SELECT item_number,color_code, SNO RID ,
         MIN(SNO) OVER(partition BY item_number,color_code)
         MIN_RID FROM   tab1  ) WHERE RID= MIN_RID;

CURSOR CUR_tab2 IS SELECT sno_2,item_number,color_code,PRIORITY FROM tab2;

son、およびsno_2の主キーです。tab1tab2

1 つのテーブルでレコードを検索するには、for loop.

SELECT NVL(MAX(SNO_2),0) INTO SNO_COUNT FROM tab2;
FOR CUR_tab1  IN CUR_NIIN_CAGE
LOOP
    -- GET THE NIIN_CAGE_PART RECORDS DATA.
    OLD_NNCGP_NIIN := CUR_tab1 .item_number;
    OLD_NNCGP_HCC  := CUR_tab1 .color_codeC;

    IF (SNO_COUNT>0 AND OLD_NNCGP_HCC IS NOT NULL) THEN  -- IF RECORDS EXISTS IN DB  
        FOR CUR_tab2 IN CUR_NIIN_HCC
        LOOP
            OLD_NIIN        := CUR_tab2.item_number;
            OLD_HCC         := CUR_tab2.color_codeC;
            NIIN_PRIORITY   := CUR_tab2.PRIORITY;

            IF (trim(OLD_NNCGP_NIIN) = trim(OLD_NIIN)
                AND trim(OLD_NNCGP_HCC)=trim(OLD_HCC)) THEN
                -- DO NOTHING
                ROW_COUNT:=0;
                PROCESSED   :=FALSE;
                EXIT;
            ELSE
                ROW_COUNT:=ROW_COUNT+1;
                PROCESSED   :=TRUE;
            END IF;
        END LOOP;
    ELSIF (SNO_COUNT=0 AND OLD_NNCGP_HCC IS NOT NULL) THEN
         PROCESSED   :=TRUE;
         ROW_COUNT:=ROW_COUNT+1;                  
    END IF;  

    IF (  PROCESSED ) THEN
        SNO_COUNT :=SNO_COUNT+1;   
        INSERT INTO tab2("SNO2","color_code","item_number","PRIORITY") 
        values (SNO_COUNT,OLD_NNCGP_HCC,OLD_NNCGP_NIIN,NULL);
        COMMIT;
    END IF;

    PROCESSED:=FALSE;
    ROW_COUNT:=0;
END LOOP;

しかし、これには約7分かかります。列を比較するより良い方法はありますか?

4

2 に答える 2

0

コードは、Agonizing Row ごとにレコードを挿入します。それが遅い理由です。SQL は set ベースの言語です。セットの喜びを受け入れて、パフォーマンスの向上を実感してください。

残念ながら、コード例全体を投稿していないため、以下は詳細が間違っている可能性がありますが、正しい考えを示しているはずです:

    SELECT NVL(MAX(SNO_2),0) INTO SNO_COUNT FROM tab2;        

    INSERT INTO tab2("SNO2","color_code","item_number","PRIORITY")  
        select SNO_COUNT+rownum,tab1.color_codeC,tab1.item_number,NULL)
        from 
        ( select distinct tab1.color_codeC,tab1.item_number
          from tab1
          where not exists
             ( select null from tab2
               where trim(tab1."color_codeC") = trim(tab2."color_codeC")
               and trim(tab1."item_number") = trim(tab2."item_number") )

データモデルにはいくつかの悪い点があります。

  1. MAX(SNO_COUNT) を使用します。この手法は拡張性がなく、マルチユーザー環境では機能しません。代わりに Oracle シーケンスを使用する必要があります。
  2. 二重引用符で囲まれた大文字と小文字が混在する識別子を使用します。これは、発生するのを待っている一連の ORA-00904 バグです。大文字の識別子を使用し、二重引用符は忘れてください。
于 2012-07-25T13:15:15.637 に答える
0

あなたが達成しようとしていることは完全には明らかではありません。1 つ以上の列の値に基づいて行の一意性を保証する通常の方法は、一意のインデックスを作成することです。

alter table <table>
  add constraint <constraint_name> unique (<column1>,..,<column_n>);

テーブルに既に存在する列値の組み合わせを持つレコードを挿入しようとすると、例外が発生します (DUP_VAL_ON_INDEX)。

于 2012-07-25T10:42:01.783 に答える