代码之家  ›  专栏  ›  技术社区  ›  Roman Kagan mianos

如何优化以下Oracle 10g查询的响应时间?

  •  0
  • Roman Kagan mianos  · 技术社区  · 16 年前

        SELECT
      /*+parallel */
      cc.customer_id      AS customer_id,
      cc.title1           AS title1,
      cc.forename1        AS forename1,
      cc.forename2        AS forename2,
      cc.surname1         AS surname1,
      cc.surname2         AS surname2,
      cc.company_flag     AS company_flag,
      cc.COMPANY_NAME     AS COMPANY_NAME,
      ext_customer_code   AS code,
      cc.customer_type    AS category,
      ca.address1         AS address1,
      ca.address2         AS address2,
      ca.address3         AS address3,
      ca.address4         AS address4,
      ca.address5         AS address5,
      ca.postcode         AS postcode,
      ca.postcode_prefix  AS postcode_prefix,
      ca.country_code     AS country_code,
      ca.town             AS town,
      ca.county           AS county,
      cc.client_id        AS client_id,
      cc.location_id      AS location_id,
      cc.data_source_id   AS dataSource_id,
      cc.SALUTATION       AS salutation,
      cc.ADDRESS_MATCHKEY AS addressMatchKey,
      ccv.vehicle_id      AS vehicle_id,
      cc.customer_name    AS customer_name,
      cv.REG_NUM          AS REG_NUM
    FROM OEM.CDB_CUSTOMERS cc,
      OEM.CDB_ADDRESSES ca,
      OEM.CDB_CUSTOMER_VEHICLES ccv,
      OEM.CDB_VEHICLES cv
    WHERE cc.client_id      = ca.client_id
    AND cc.address_matchkey = ca.address_matchkey
    AND cc.location_id      = ca.location_id
    AND cc.customer_id      = ccv.customer_id
    AND cc.client_id        = ccv.client_id
    AND cc.LOCATION_ID      = ccv.LOCATION_ID
    AND ccv.vehicle_id      = cv.vehicle_id
    AND ccv.client_id       = cv.CLIENT_ID
    AND ccv.LOCATION_ID     = cv.LOCATION_ID
    AND cv.LOCATION_ID      = 1
    AND ccv.rejection_flag  = 'N'
    AND ccv.owner_status   IS NOT NULL
    AND cc.client_id        = 1776
    AND ca.client_id        = 1776
    AND ca.country_code     ='UK'
    AND ca.area_id         IN
      ( SELECT start_code postcode_id FROM MDB_FORMAT WHERE NAME = 'PC%1776'
      )
    AND cv.model_id IN
      ( SELECT m.start_code model_id FROM MDB_FORMAT m WHERE m.NAME = '10_RWMOD'
      )
    ORDER BY customer_name,
      town,
      postcode
    

    以下是执行计划:

    | Id  | Operation                        | Name                     | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                                                                                                                
    |   0 | SELECT STATEMENT                 |                          |     1 |   317 |   320   (1)| 00:00:04 |                                                                                                                                                                                                
    |   1 |  SORT ORDER BY                   |                          |     1 |   317 |   320   (1)| 00:00:04 |                                                                                                                                                                                                
    |   2 |   NESTED LOOPS                   |                          |     1 |   317 |   319   (1)| 00:00:04 |                                                                                                                                                                                                
    |   3 |    NESTED LOOPS                  |                          |     1 |   299 |   319   (1)| 00:00:04 |                                                                                                                                                                                                
    |   4 |     NESTED LOOPS                 |                          |     1 |   273 |   319   (1)| 00:00:04 |                                                                                                                                                                                                
    |*  5 |      HASH JOIN                   |                          |     8 |  1992 |   314   (1)| 00:00:04 |                                                                                                                                                                                                
    |   6 |       TABLE ACCESS BY INDEX ROWID| CDB_ADDRESSES            |    10 |  1060 |     1   (0)| 00:00:01 |                                                                                                                                                                                                
    |   7 |        NESTED LOOPS              |                          |   501 | 62124 |    30   (0)| 00:00:01 |                                                                                                                                                                                                
    |*  8 |         INDEX RANGE SCAN         | MDB_FORMAT_PK            |    48 |   864 |     1   (0)| 00:00:01 |                                                                                                                                                                                                
    |*  9 |         INDEX RANGE SCAN         | CDB_ADDRESSES_SMM_IDX1   |    10 |       |     1   (0)| 00:00:01 |                                                                                                                                                                                                
    |  10 |       TABLE ACCESS BY INDEX ROWID| CDB_CUSTOMERS            | 28544 |  3484K|   283   (0)| 00:00:04 |                                                                                                                                                                                                
    |* 11 |        INDEX RANGE SCAN          | CDB_CUSTOMERS_UK1        | 28544 |       |    38   (0)| 00:00:01 |                                                                                                                                                                                                
    |* 12 |      TABLE ACCESS BY INDEX ROWID | CDB_CUSTOMER_VEHICLES    |     1 |    24 |     1   (0)| 00:00:01 |                                                                                                                                                                                                
    |* 13 |       INDEX RANGE SCAN           | CDB_CUSTOMER_VEHICLES_PK |     1 |       |     1   (0)| 00:00:01 |                                                                                                                                                                                                
    |  14 |     TABLE ACCESS BY INDEX ROWID  | CDB_VEHICLES             |     1 |    26 |     1   (0)| 00:00:01 |                                                                                                                                                                                                
    |* 15 |      INDEX RANGE SCAN            | CDB_VEHICLES_PREF_IND    |     1 |       |     1   (0)| 00:00:01 |                                                                                                                                                                                                
    |* 16 |    INDEX RANGE SCAN              | MDB_FORMAT_PK            |     1 |    18 |     1   (0)| 00:00:01 |                                                                                                                                                                                                
    

    谓词信息(由操作id标识):

       5 - access("CC"."CLIENT_ID"="CA"."CLIENT_ID" AND "CC"."ADDRESS_MATCHKEY"="CA"."ADDRESS_MATCHKEY"                                                                                                                                                                                                          
                  AND "CC"."LOCATION_ID"="CA"."LOCATION_ID")                                                                                                                                                                                                                                                     
       8 - access("NAME"='PC%1776')                                                                                                                                                                                                                                                                              
       9 - access("CA"."CLIENT_ID"=1776 AND "CA"."AREA_ID"=TO_NUMBER("START_CODE") AND                                                                                                                                                                                                                           
                  "CA"."COUNTRY_CODE"='UK' AND "CA"."LOCATION_ID"=1)                                                                                                                                                                                                                                             
      11 - access("CC"."CLIENT_ID"=1776 AND "CC"."LOCATION_ID"=1)                                                                                                                                                                                                                                                
      12 - filter("CCV"."OWNER_STATUS" IS NOT NULL AND "CCV"."REJECTION_FLAG"='N')                                                                                                                                                                                                                               
      13 - access("CCV"."CLIENT_ID"=1776 AND "CC"."CUSTOMER_ID"="CCV"."CUSTOMER_ID" AND                                                                                                                                                                                                                          
                  "CCV"."LOCATION_ID"=1)                                                                                                                                                                                                                                                                         
           filter("CCV"."LOCATION_ID"=1)                                                                                                                                                                                                                                                                         
      15 - access("CCV"."VEHICLE_ID"="CV"."VEHICLE_ID" AND "CV"."CLIENT_ID"=1776 AND                                                                                                                                                                                                                             
                  "CV"."LOCATION_ID"=1)                                                                                                                                                                                                                                                                          
      16 - access("M"."NAME"='10_RWMOD')                                                                                                                                                                                                                                                                         
           filter("CV"."MODEL_ID"=TO_NUMBER("M"."START_CODE"))                                                                                                                                                                                                                                                   
    41 rows selected
    
    3 回复  |  直到 16 年前
        1
  •  1
  •   Justin K    16 年前

    步骤1:确保查询是正确的。我不确定您的数据模型是什么,但我注意到您说“SELECT start\u code postcode\u id”和“SELECT m.start\u code model\u id”。您的意思是为了两个目的而对同一字段使用别名吗?

    第二步:分析表格。过期的统计信息可能会导致优化器选择错误的计划。

    步骤3:在FROM子句中编写连接条件(例如,“table1 join table2 ON(table1.id=table2.id))。这使您、优化器和任何阅读您的代码的人都清楚地知道您要做什么。重新安排已经组织好的东西更容易。

    步骤4:重复步骤1。

    第五步:等你到了那里我们再谈。

        2
  •  1
  •   Justin    16 年前

        3
  •  1
  •   Gary Myers    16 年前

    “根据筛选条件,它返回大约18000到8000行。”

    WHERE cc.client_id      = ca.client_id
    ...
    AND cc.client_id        = 1776
    AND ca.client_id        = 1776
    

    第9项和第11项都有1776过滤器,但是第5项确保它们匹配。这是多余的,但可能会影响基数估计。

    推荐文章