使用减去oracle优化插入查询

时间:2017-05-27 15:47:39

标签: oracle performance query-optimization

希望优化一项需要更长时间才能完成的重要声明。

基本上该过程将:

1)通过5个插入逐个插入NG_ORGANIZATION_CATEGORY_GTMP上的数据。这些DML使用每个查询需要10秒。从上一个跟踪中,这些DML插入了以下行数:

Insert 1 - 292770
Insert 2 - 106648
Insert 3 - 67358
Insert 4 - 47775
Insert 5 - 6147

2)运行有问题的查询,仅在表NG_ORGANIZATION_CATEGORY上插入6行(此表有大约414k行)。

INSERT INTO NG_ORGANIZATION_CATEGORY(ORGANIZATION_ID,CATEGORY_CODE,ADDED_DATE)
    SELECT ORGANIZATION_ID,CATEGORY_CODE,:B1 AS ADDED_DATE 
    FROM NG_ORGANIZATION_CATEGORY_GTMP 
    WHERE (ORGANIZATION_ID,CATEGORY_CODE) IN (
            SELECT ORGANIZATION_ID,CATEGORY_CODE 
            FROM NG_ORGANIZATION_CATEGORY_GTMP
            MINUS 
            SELECT ORGANIZATION_ID,CATEGORY_CODE 
            FROM NG_ORGANIZATION_CATEGORY );

3)处理从NG_ORGANIZATION_CATEGORY表中删除数据。它也很好。

DELETE FROM NG_ORGANIZATION_CATEGORY
WHERE
 (ORGANIZATION_ID,CATEGORY_CODE) IN ( SELECT ORGANIZATION_ID,CATEGORY_CODE
  FROM NG_ORGANIZATION_CATEGORY MINUS SELECT ORGANIZATION_ID,CATEGORY_CODE
  FROM NG_ORGANIZATION_CATEGORY_GTMP );

以下是有问题的插页的跟踪:

SQL ID: gwxs083gcfdd2 Plan Hash: 2436575860

INSERT INTO NG_ORGANIZATION_CATEGORY(ORGANIZATION_ID,CATEGORY_CODE,ADDED_DATE)
   SELECT ORGANIZATION_ID,CATEGORY_CODE,:B1 AS ADDED_DATE FROM
  NG_ORGANIZATION_CATEGORY_GTMP WHERE (ORGANIZATION_ID,CATEGORY_CODE) IN (
  SELECT ORGANIZATION_ID,CATEGORY_CODE FROM NG_ORGANIZATION_CATEGORY_GTMP
  MINUS SELECT ORGANIZATION_ID,CATEGORY_CODE FROM NG_ORGANIZATION_CATEGORY )



call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1   6704.07    6705.98          2  424814954         25           6
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2   6704.07    6705.98          2  424814954         25           6

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 146     (recursive depth: 1)
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         0          0          0  LOAD TABLE CONVENTIONAL  (cr=424814954 pr=2 pw=0 time=923492126 us)
         6          6          6   FILTER  (cr=424814953 pr=0 pw=0 time=1667461141 us)
    414050     414050     414050    TABLE ACCESS FULL NG_ORGANIZATION_CATEGORY_GTMP (cr=1023 pr=0 pw=0 time=121231 us cost=2 size=35 card=1)
         6          6          6    MINUS  (cr=424813930 pr=0 pw=0 time=2409881660 us)
    414050     414050     414050     SORT UNIQUE NOSORT (cr=423573150 pr=0 pw=0 time=2406932080 us cost=3 size=35 card=1)
    414050     414050     414050      TABLE ACCESS FULL NG_ORGANIZATION_CATEGORY_GTMP (cr=423573150 pr=0 pw=0 time=2406112290 us cost=2 size=35 card=1)
    414044     414044     414044     INDEX UNIQUE SCAN NG_ORG_CATEGORY_PK (cr=1240780 pr=0 pw=0 time=2134347 us cost=2 size=11 card=1)(object id 108100)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  gc cr grant 2-way                               1        0.00          0.00
  db file sequential read                         2        0.13          0.13
  gc current grant 2-way                          6        0.00          0.00
********************************************************************************

你能帮助我,让我知道如何调整这个查询?我想添加一个并行提示,但由于查询上的MINUS,它会被忽略。

如果您有任何想法以及是否需要任何其他信息,请与我们联系。

感谢你的注意力。

提前致谢,

威尔

3 个答案:

答案 0 :(得分:0)

您可以使用内部联接而不是where()IN

INSERT INTO NG_ORGANIZATION_CATEGORY(ORGANIZATION_ID,CATEGORY_CODE,ADDED_DATE)
SELECT ORGANIZATION_ID,CATEGORY_CODE,:B1  
FROM NG_ORGANIZATION_CATEGORY_GTMP 
INNER JOIN (
    SELECT ORGANIZATION_ID,CATEGORY_CODE 
    FROM NG_ORGANIZATION_CATEGORY_GTMP
    MINUS 
    SELECT ORGANIZATION_ID,CATEGORY_CODE 
    FROM NG_ORGANIZATION_CATEGORY 
) T1 on NG_ORGANIZATION_CATEGORY_GTMP.ORGANIZATION_ID =  T1.ORGANIZATION_ID 
          and NG_ORGANIZATION_CATEGORY_GTMP.CATEGORY_CODE = T1.CATEGORY_CODE

和一个简单的提示删除别名表单选择(没用)

答案 1 :(得分:0)

根据您的查询,只有在类别表中不存在数据时才希望将数据插入到gtmp表中。 您可以尝试以下查询:

  INSERT INTO NG_ORGANIZATION_CATEGORY(ORGANIZATION_ID,CATEGORY_CODE,ADDED_DATE)
     SELECT ORGANIZATION_ID,CATEGORY_CODE,:B1 AS ADDED_DATE FROM
    NG_ORGANIZATION_CATEGORY_GTMP T1 WHERE NOT EXISTS (
SELECT 1 FROM NG_ORGANIZATION_CATEGORY T2 WHERE  T1.ORGANIZATION_ID=T2.ORGANIZATION_ID AND T1.CATEGORY_CODE=T2.CATEGORY_CODE);

答案 2 :(得分:0)

您可以使用MERGE语句仅使用源表中不存在的行填充目标表:

merge into ng_organization_category noc
using ( select distinct organization_id,
               category_code
        from ng_organization_category_gtmp ) gtmp
  on ( gtmp.organization_id =  noc.organization_id 
       and gtmp.category_code = noc.category_code )
when not matched then
    insert (organization_id, category_code, added_date)
    values (gtmp.organization_id, gtmp.category_code, :B1)
/

USING子查询中的DISTINCT可能没有必要,它取决于您的源数据。 (如果GTMP表包含它们,您现有的INSERT语句将插入多个(organization_id, category_code)实例,因此可能无关紧要。)