簡體   English   中英

Oracle SQL SELECT子查詢優化

[英]Oracle SQL SELECT subquery Optimization

我需要優化SELECT查詢以提高性能。 我正在使用ORACLE 10g。 以下是我的表格:

CREATE TABLE TRNSCTN
(
  TRNSCTN_ID              VARCHAR2(32)   NOT NULL,
  TRNSCTN_DOC         VARCHAR2(60)   NOT NULL,
  TRNSCTN_TYPE            VARCHAR2(60)   NOT NULL,
  STATUS                  NUMBER         NOT NULL,
  TRNSCTN_CREATEDDATE     DATE           NOT NULL,
  TRNSCTN_CREATEDBY       VARCHAR2(60)   NOT NULL,
  TRNSCTN_CHANGEDDATE     DATE           NOT NULL,
  TRNSCTN_CHANGEDBY       VARCHAR2(60)   NOT NULL,
  PARENT_LINK             VARCHAR2(32)   NULL,
  PT_NAME         VARCHAR2(255)  NULL,
  APP_ID          VARCHAR2(255)  NULL,
  DIRECTION               NUMBER         NULL,
  CONSTRAINT PK_TRNSCTN_ID PRIMARY KEY (TRNSCTN_ID)
);

以下是一些記錄:

Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B91','DOC1','TYPE1',5501,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B92','PT_SEMO','APP1',2 );
Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B92','DOC2','TYPE1',5502,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B92','PT_SEMO','APP1',1 );
Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B93','DOC3','TYPE2',5503,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B93','PT_SEMO','APP3',2 );
Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B94','DOC1','TYPE2',5504,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B91','PT_SEMO','APP1',2 );
Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B95','DOC2','TYPE1',5505,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B93','PT_SEMO','APP1',1 );
Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B96','DOC1','TYPE1',5506,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B92','PT_SEMO','APP3',2 );
Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B97','DOC2','TYPE1',5507,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B99','PT_SEMO','APP1',1 );
Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B98','DOC3','TYPE2',5508,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B93','PT_SEMO','APP1',1 );
Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B99','DOC1','TYPE2',5509,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B91','PT_SEMO','APP1',1 );
Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B910','DOC2','TYPE1',5510,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B93','PT_SEMO','APP3',1 );
Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B911','DOC1','TYPE1',5511,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B92','PT_SEMO','APP1',2 );
Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B912','DOC2','TYPE1',5512,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B913','PT_SEMO','APP1',1 );
Insert into TRNSCTN (TRNSCTN_ID,TRNSCTN_DOC,TRNSCTN_TYPE,STATUS,TRNSCTN_CREATEDDATE,TRNSCTN_CREATEDBY,TRNSCTN_CHANGEDDATE,TRNSCTN_CHANGEDBY,PARENT_LINK,PT_NAME,APP_ID,DIRECTION) values ('E840496554B913','DOC3','TYPE2',5513,to_date('01-MAY-13','DD-MON-RR'),'usr1',to_date('01-MAY-13','DD-MON-RR'),'usr1','E840496554B911','PT_SEMO','APP3',2 );

現在,這是我的SELECT查詢

SELECT TRNSCTN_ID, 
       TRNSCTN_DOC, 
       TRNSCTN_TYPE, 
       STATUS, 
       TRNSCTN_CREATEDDATE, 
       TRNSCTN_CREATEDBY, 
       TRNSCTN_CHANGEDDATE, 
       TRNSCTN_CHANGEDBY, 
       PARENT_LINK, 
       CASE 
          WHEN (SELECT COUNT(*) FROM TRNSCTN sub WHERE TRNSCTN_ID=sub.PARENT_LINK) = 0 THEN 'false' 
          ELSE 'true' 
       END AS CHILDCNT, 
       PT_NAME, 
       APP_ID, 
       DIRECTION 
FROM TRNSCTN

當我使用子查詢來確定記錄是否具有父鏈接時,針對數百萬條記錄的查詢會變得非常慢。

抱歉,SQLFIDDLE已關閉,因此無法使用它。

我想知道,是否還有另一種方法可以重寫查詢以優化性能。

請讓我知道優化的SELECT查詢。

謝謝。

您可以使用左連接,如我在下面寫的,您可以考慮給出並行提示(例如/ * + parallel * /)

    SELECT sub.TRNSCTN_ID,
    sub.TRNSCTN_DOC,
    sub.TRNSCTN_TYPE,
    sub.STATUS,
    sub.TRNSCTN_CREATEDDATE,
    sub.TRNSCTN_CREATEDBY,
    sub.TRNSCTN_CHANGEDDATE,
    sub.TRNSCTN_CHANGEDBY,
    sub.PARENT_LINK,
    DECODE(prnt.trnsctn_id, null, 'false', 'true') AS CHILDCNT,
    sub.PT_NAME,
    sub.APP_ID,
    sub.DIRECTION
    from TRNSCTN sub
    left join TRNSCTN prnt
    on sub.parent_link = prnt.trnsctn_id;

也許您可以使用自我聯接而不是子查詢

即puesdo代碼:

SELECT <the_columns> FROM Transactions maintrans
LEFT OUTER JOIN (SELECT DISTINCT ParentID FROM Transactions) subtrans
ON maintrans.TranscationID = subtrans.ParentID

現在,如果subtrans.ParentID為NULL,則相當於沒有父級的事務

SELECT TRNSCTN_ID, 
       TRNSCTN_DOC, 
       TRNSCTN_TYPE, 
       STATUS, 
       TRNSCTN_CREATEDDATE, 
       TRNSCTN_CREATEDBY, 
       TRNSCTN_CHANGEDDATE, 
       TRNSCTN_CHANGEDBY, 
       PARENT_LINK, 
       CASE 
          WHEN NOT EXISTS (SELECT 1
                           FROM   TRNSCTN sub
                           WHERE  t.TRNSCTN_ID=sub.PARENT_LINK)
          THEN 'false' 
          ELSE 'true' 
       END AS CHILDCNT, 
       PT_NAME, 
       APP_ID, 
       DIRECTION 
FROM TRNSCTN t;

SQLFIDDLE

SELECT 
  TRNSCTN_ID,
  TRNSCTN_DOC,
  TRNSCTN_TYPE,
  STATUS,
  TRNSCTN_CREATEDDATE,
  TRNSCTN_CREATEDBY,
  TRNSCTN_CHANGEDDATE,
  TRNSCTN_CHANGEDBY,
  PARENT_LINK,
  CHILDCNT,
  PT_NAME,
  APP_ID,
  DIRECTION
FROM
  (SELECT /*+use_hash(TRNSCTN, TRNSCTN1) */
    TRNSCTN.TRNSCTN_ID,
    TRNSCTN.TRNSCTN_DOC,
    TRNSCTN.TRNSCTN_TYPE,
    TRNSCTN.STATUS,
    TRNSCTN.TRNSCTN_CREATEDDATE,
    TRNSCTN.TRNSCTN_CREATEDBY,
    TRNSCTN.TRNSCTN_CHANGEDDATE,
    TRNSCTN.TRNSCTN_CHANGEDBY,
    TRNSCTN.PARENT_LINK,
    DECODE(COUNT(TRNSCTN1.TRNSCTN_ID) over (partition BY TRNSCTN.PARENT_LINK), 0, 'false', 'true') CHILDCNT,
    TRNSCTN.PT_NAME,
    TRNSCTN.APP_ID,
    TRNSCTN.DIRECTION,
    rank() over (partition BY TRNSCTN.TRNSCTN_ID order by TRNSCTN1.TRNSCTN_ID) r
  FROM
    TRNSCTN TRNSCTN,
    TRNSCTN TRNSCTN1
  WHERE
    TRNSCTN.PARENT_LINK=TRNSCTN1.TRNSCTN_ID(+)
  )
WHERE
  r=1;

如果需要,您可以插入並行提示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM