0

我有两张桌子tab1tab2. tab1有 39000 条记录和tab215000 条记录。tab1并且tab2都有两个共同的列说item_numbercolor_code。但是 in tab1, color_code可能是 null 但不是 in tab2item_number在两个表中都不为空。在tab2我必须插入一行(基于两列的唯一行)数据tab1。为此,我编写了这样的程序。它将比较每一行,但时间太长。有什么方法可以提高性能。先取两个游标:

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

要在一个表中查找记录,我使用的是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 是一种基于集合的语言。所以拥抱套装的喜悦,看看你的表现会提高。

不幸的是,您还没有发布整个代码示例,因此以下内容可能在细节上是错误的,但它应该显示您的正确想法:

    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

目前尚不完全清楚您要达到的目标。基于一个或多个列值确保行唯一性的常规方法是创建唯一索引。

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

每当您尝试插入包含表中已存在的列值组合的记录时,将引发异常 (DUP_VAL_ON_INDEX)。

于 2012-07-25T10:42:01.783 回答