2017-05-27 52 views
2

希望优化需要更长时间才能完成的重要语句。优化插入带减号的查询

基本上过程中会:

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,它将被忽略。

请让我知道你是否有任何想法,如果你需要任何其他信息。

感谢您的关注。

由于提前,

威尔

回答

0

你可以使用内部联接,而不是在那里()的

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 

和一个简单的提示删除该别名形式的选择(是不是有用)

+0

非常感谢..我会试试这个! – Will

+0

嗨@scaisEdge ...我工作并在不到1秒内跑完了!我只需要确认数据,但是在插入之前我运行了一个MINUS计数,并且插入了相同数量的数据。我将在周一与开发人员核对并回到这篇文章!就目前而言,谢谢你,你是男人! – Will

+0

以及如果我的答案是正确的,请将其标记为已接受...看到这里如何 http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – scaisEdge

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); 
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子查询可能不是必需的,它取决于您的源数据。 (您现有的INSERT语句会插入多个的实例,如果GTMP表具有它们,所以可能没关系。)

+0

嗨@APC ..感谢您的帮助!我将等待DEV验证scaisEdge提供的建议,如果它没有用处。我会尝试您的指示!非常感谢您的帮助。 – Will