[英]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;
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.