2017-10-06 23 views
2

私は、この特定のクエリのパフォーマンスの問題を抱えている:Oracle 11gの:クエリのパフォーマンスの最適化

SELECT ID, 
     NAME, 
     CREATION_DATE, 
     MODIFICATION_DATE, 
     CREATION_USER, 
     MODIFICATION_USER, 
     CODE, 
     START_DATE, 
     TO_CHAR(ANSWER) AS ANSWER, 
     STATUS, 
     RESUME, 
     REQUIRED, 
     RTRIM(
     XMLAGG(
      XMLELEMENT(E,QW.WARD_ID,',').EXTRACT('//text()') 
      ORDER BY QW.WARD_ID 
     ).GetClobVal(), 
     ',' 
     ) AS wards 
FROM RD_QUESTIONS Q 
     LEFT JOIN RD_QUESTIONS_WARDS QW ON QW.QUESTION_ID = ID 
GROUP BY ID, 
     NAME, 
     CREATION_DATE, 
     MODIFICATION_DATE, 
     CREATION_USER, 
     MODIFICATION_USER, 
     CODE, 
     START_DATE, 
     TO_CHAR(ANSWER), 
     STATUS, 
     RESUME, 
     REQUIRED 

DDL

CREATE TABLE RD_QUESTIONS(
    ID NUMBER(38, 0), 
    NAME VARCHAR(255) NOT NULL, 
    CREATION_DATE TIMESTAMP(6), 
    MODIFICATION_DATE TIMESTAMP(6), 
    CREATION_USER VARCHAR(20), 
    MODIFICATION_USER VARCHAR(20), 
    SECTION_ID NUMBER(38, 0), 
    CHAPTER_ID NUMBER(38, 0), 

    CONSTRAINT RD_QUESTIONS_PK3 PRIMARY KEY (ID), 
); 

CREATE TABLE RD_QUESTIONS_WARDS(
    QUESTION_ID NUMBER(38, 0), 
    WARD_ID NUMBER(38, 0), 

    CONSTRAINT RD_QUESTIONS_WARDS_PK4 PRIMARY KEY (QUESTION_ID, WARD_ID), 
    CONSTRAINT RD_QUESTIONS_FK4 FOREIGN KEY (QUESTION_ID) REFERENCES RD_QUESTIONS(ID) 
); 

は、問題は、計算が本当に遅いです声明RTRIM(XMLAGG(XMLELEMENT(E,WARD_ID,',').EXTRACT('//text()') ORDER BY WARD_ID).GetClobVal(),',') AS wards です。

私が探している結果は、すべての一致IDが文字列に結合された「wards」という名前の列です。

パフォーマンスの優れたソリューションをお持ちの方はいらっしゃいますか?集約WARD_ID文字列の長さに行くことはありませんされている場合、また、

SELECT Q.ID, 
     Q.NAME, 
     Q.CREATION_DATE, 
     Q.MODIFICATION_DATE, 
     Q.CREATION_USER, 
     Q.MODIFICATION_USER, 
     Q.CODE, 
     Q.START_DATE, 
     TO_CHAR(Q.ANSWER) AS ANSWER, 
     Q.STATUS, 
     Q.RESUME, 
     Q.REQUIRED, 
     QW.wards 
FROM RD_QUESTIONS Q 
     LEFT JOIN (
     SELECT Question_ID, 
       RTRIM(
        XMLAGG(
        XMLELEMENT(E,WARD_ID,',').EXTRACT('//text()') 
        ORDER BY WARD_ID 
       ).GetClobVal(), 
       ',' 
       ) AS wards 
     FROM RD_QUESTIONS_WARDS 
     GROUP BY QUESTION_ID 
     ) QW 
     ON QW.QUESTION_ID = Q.ID 

:あなたが参加し、テーブルのすべての列によってグループには必要ありませんので、

+0

2つのテーブルのDDLを与え、さまざまな列がそのように属するテーブルを示すために、あなたのクエリを編集することができますが、あなたの選択肢に大きな違いを生むだろう。私。それは 'Q.WARD_ID'か' QW.WARD_ID'ですか(他の列にも同様です) – MT0

答えて

3

あなたは、サブクエリに集約を移動することができますであることをあなたが使用できる4000文字以上LISTAGG

FROM RD_QUESTIONS Q 
     LEFT JOIN (
     SELECT Question_ID, 
       LISTAGG(WARD_ID, ',') WITHIN GROUP (ORDER BY WARD_ID) AS wards 
     FROM RD_QUESTIONS_WARDS 
     GROUP BY QUESTION_ID 
     ) QW 
     ON QW.QUESTION_ID = Q.ID 
+0

LISTAGGはトリックをしました、ありがとうございます。 – Pietro

関連する問題