2013-11-18 2 views
0

Мне нужно оптимизировать запрос SELECT, чтобы повысить производительность. Я использую ORACLE 10g. Ниже мой стол:Оптимизация подзапроса Oracle SQL SELECT

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 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.

спасибо.

ответ

3

Вы можете использовать левый присоединиться, как я писал ниже, и вы можете рассмотреть вопрос о предоставлении параллельной подсказки (например,/* + параллельно * /)

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; 
0

Может быть, вы могли бы использовать автообъединение, а не подзапрос

т.е. puesdo-код:

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

Теперь, когда subtrans.ParentID является NULL, будет приравнять к сделке без родителей

0
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

0
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; 

Вы можете вставить параллельный намек, если он

Обязательное
Смежные вопросы