Оптимизация запросов Oracle (с объединениями и вложенными выборками) - PullRequest
0 голосов
/ 05 октября 2011

Я хочу оптимизировать запрос ниже.У меня нет опыта по методам оптимизации.Пожалуйста, предложите мне что-то, что может помочь мне оптимизировать запрос ниже:

SELECT 
       ad.towncity,
       ad.state,

FROM   promptdescription pd,
       osquestion osq,

WHERE  acc.status = 1
AND    acc.customer_id = con.customer_id
       ap.os_id
AND NOT EXISTS (SELECT 1
                FROM   osquestion osq2,
                       orderedproduct op3
                WHERE  osq2.ext_quest_id = pd.id
                AND osq2.question_id > osq.question_id

Ответы [ 2 ]

0 голосов
/ 05 октября 2011

Прежде всего, определите все поля PK во всех таблицах запроса. Затем измените условие where в соответствии с последовательностью полей PK, созданных в таблице oracle db.

0 голосов
/ 05 октября 2011

Во-первых, ваш запрос эквивалентен:

SELECT ACC.id
     , OP.rootprODUCT_ID
     , ACC.externALBILLID
     , CON.firstnAME
     , CON.lastnaME
     , AD.line1
     , NVL ( AD.line2 , '' ) AS     LINE2
     , AD.towncity
     , AD.state
     , AD.postalzipcode
     , PROD.billingcode
     , PD.name               as     Prompt_Name
     , OSQ.current_value
  FROM promptdescription             PD
  JOIN osquestion                   OSQ ON        OSQ.ext_quest_id  =         PD.id
  JOIN osquestiongroup           OSQGRP ON     OSQGRP.qg_id         =        OSQ.qg_id
  JOIN osparamdatacapability OSPARAMCAP ON OSPARAMCAP.cap_id        =     OSQGRP.cap_id
  JOIN orderedservice                OS ON         OS.id            = OSPARAMCAP.os_id
  JOIN servicedescription            SD ON         SD.id            =         OS.svcdesc_id
  JOIN orderedproduct                OP ON         OP.ordservice_id =         OS.id
  JOIN productdescription          PROD ON       PROD.id            =         OP.proddesc_id_root
  JOIN customerorder                 CO ON         CO.id            =         OP.custorder_id
  JOIN account                      ACC ON        ACC.id            =         OP.account_id
  JOIN contact                        C ON          C.customer_id   =        ACC.customer_id
  JOIN address                     ADDR ON       ADDR.id            =          C.address_id
  JOIN contact                      CON ON        CON.customer_id   =        ACC.customer_id
  JOIN address                       AD ON         AD.id            =        CON.address_id
 WHERE PD.name IN ( 'County Code' , 'Service Occurrence' , 'VoIP Port' , 'VoIP MTA MAC address' , 'Primary TN' , 'HSDS CM MAC address' , 'VoIP FQDN' , 'Caller Id' )
   AND OSQ.current_value IS NOT NULL
   AND SD.name in ( 'Voice over IP' )
   AND OP.resultingaction <> 2
   AND OP.status = 10
   AND ACC.status = 1
   AND EXISTS ( SELECT 1
       FROM ORDEREDPRODUCT OP1
       WHERE OP1.PRODUCT_ID = OP.PRODUCT_ID
       AND OP1.STATUS = 10
       HAVING MAX ( OP1.ID ) = OP.ID )
   AND CO.ID IN ( select ID
       FROM CUSTOMERORDER CO1
       where CO1.CUSTOMER_ID = ACC.CUSTOMER_ID
       AND CO1.STATUS = 10 )
   AND NOT EXISTS ( SELECT 1
                      FROM OSQUESTION OSQ2
                         , ORDEREDSERVICE OS1
                         , OSPARAMDATACAPABILITY OSPARAMCAP1
                         , OSQUESTIONGROUP OSQGRP1
                         , ORDEREDPRODUCT OP3
                     where OSQ2.EXT_QUEST_ID = PD.ID
                       AND OSQ2.QUESTION_ID > OSQ.QUESTION_ID
                       AND OSQ2.PROVISIONED_VALUE = OSQ.CURRENT_VALUE
                       AND OSQ2.CURRENT_VALUE != OSQ.CURRENT_VALUE
                       AND PD.NAME IN ( 'Primary TN'
                                      , 'VoIP MTA MAC address'
                                      , 'HSDS CM MAC address' )
                       AND OSQGRP1.QG_ID = OSQ2.QG_ID
                       AND OSPARAMCAP1.CAP_ID = OSQGRP1.CAP_ID
                       AND OS1.ID = OSPARAMCAP1.OS_ID
                       AND OP.ROOTPRODUCT_ID = OP3.ROOTPRODUCT_ID
                       AND OP3.ORDSERVICE_ID = OS1.ID
                       AND OP3.STATUS = 10 )
 ORDER BY ACC.EXTERNALBILLID
        , OP.ROOTPRODUCT_ID
        , CO.ID

Примечания:

  • вы присоединяетесь к Контакту и Адресу дважды (это бесполезно).
  • Если вам нужен заказанный продукт с максимальным идентификатором, вы можете использовать полусоединение (об этом вы найдете другие вопросы).
  • Проверка CO.ID по таблице контактов может быть выполнена в части JOIN.

Я мог бы переписать первую часть как:

SELECT ACC.id
     , OP.rootprODUCT_ID
     , ACC.externALBILLID
     , CON.firstnAME
     , CON.lastnaME
     , AD.line1
     , NVL ( AD.line2 , '' ) AS     LINE2
     , AD.towncity
     , AD.state
     , AD.postalzipcode
     , PROD.billingcode
     , PD.name               as     Prompt_Name
     , OSQ.current_value
  FROM promptdescription             PD
  JOIN osquestion                   OSQ  ON        OSQ.ext_quest_id  =         PD.id
  JOIN osquestiongroup           OSQGRP  ON     OSQGRP.qg_id         =        OSQ.qg_id
  JOIN osparamdatacapability OSPARAMCAP  ON OSPARAMCAP.cap_id        =     OSQGRP.cap_id
  JOIN orderedservice                OS  ON         OS.id            = OSPARAMCAP.os_id
  JOIN servicedescription            SD  ON         SD.id            =         OS.svcdesc_id
  JOIN orderedproduct                OP  ON         OP.ordservice_id =         OS.id
  JOIN productdescription          PROD  ON       PROD.id            =         OP.proddesc_id_root
  JOIN account                      ACC  ON        ACC.id            =         OP.account_id
  JOIN contact                        C  ON          C.customer_id   =        ACC.customer_id
  JOIN address                     ADDR  ON       ADDR.id            =          C.address_id
  JOIN contact                      CON  ON        CON.customer_id   =        ACC.customer_id
  JOIN address                       AD  ON         AD.id            =        CON.address_id
  JOIN customerorder                 CO  ON         CO.id            =         OP.custorder_id
                                        AND         CO.customer_id   =        ACC.customer_id
  LEFT JOIN orderedproduct    ismaxopid  ON ismaxopid.product_id = op.product_id
                                        AND ismaxopid.status = 10
                                        AND ismaxopid.id > op.id
 WHERE PD.name IN ( 'County Code' , 'Service Occurrence' , 'VoIP Port' , 'VoIP MTA MAC address' , 'Primary TN' , 'HSDS CM MAC address' , 'VoIP FQDN' , 'Caller Id' )
   AND OSQ.current_value IS NOT NULL
   AND SD.name in ( 'Voice over IP' )
   AND OP.resultingaction <> 2
   AND OP.status = 10
   AND ACC.status = 1
   AND ismaxopid.id IS NULL
   AND NOT EXISTS ( SELECT 1
                      FROM OSQUESTION OSQ2
                         , ORDEREDSERVICE OS1
                         , OSPARAMDATACAPABILITY OSPARAMCAP1
                         , OSQUESTIONGROUP OSQGRP1
                         , ORDEREDPRODUCT OP3
                     where OSQ2.EXT_QUEST_ID = PD.ID
                       AND OSQ2.QUESTION_ID > OSQ.QUESTION_ID
                       AND OSQ2.PROVISIONED_VALUE = OSQ.CURRENT_VALUE
                       AND OSQ2.CURRENT_VALUE != OSQ.CURRENT_VALUE
                       AND PD.NAME IN ( 'Primary TN'
                                      , 'VoIP MTA MAC address'
                                      , 'HSDS CM MAC address' )
                       AND OSQGRP1.QG_ID = OSQ2.QG_ID
                       AND OSPARAMCAP1.CAP_ID = OSQGRP1.CAP_ID
                       AND OS1.ID = OSPARAMCAP1.OS_ID
                       AND OP.ROOTPRODUCT_ID = OP3.ROOTPRODUCT_ID
                       AND OP3.ORDSERVICE_ID = OS1.ID
                       AND OP3.STATUS = 10 )
 ORDER BY ACC.EXTERNALBILLID
        , OP.ROOTPRODUCT_ID
        , CO.ID

Часть NOT EXISTS все еще нуждается в улучшении.

...