Как оптимизировать время ответа на следующий запрос Oracle 10g? - PullRequest
0 голосов
/ 04 августа 2010

Как оптимизировать время ответа на следующий запрос:

    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 |                                                                                                                                                                                                

Информация о предикате (идентифицируется идентификатором операции):

   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 ]

1 голос
/ 04 августа 2010

Обычно хорошей идеей является маскировка информации вашего клиента, например, изменение названия компании на CO или XXX, вам даже не нужно имя схемы для оптимизации запроса.

1 голос
/ 05 августа 2010

"Возвращает от 18000 до 8000 строк в зависимости от критериев фильтра."План объяснения указывает, что он ожидает вернуть 1 строку (и это, как правило, потому что НИКОГДА не ожидает возврата 0 строк).

Я предполагаю, что некоторые из оценок мощности неверны.Один элемент, который может сбить с толку, это

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

Элементы 9 и 11 имеют фильтр 1776, но затем элемент 5 проверяет, совпадают ли они.Это избыточно, но может влиять на оценку количества элементов.

1 голос
/ 04 августа 2010

Шаг 1: убедитесь, что запрос правильный. Я не уверен, какая у вас модель данных, но я заметил, что вы говорите "SELECT start_code postcode_id" и "SELECT m.start_code model_id". Вы имеете в виду псевдоним одного поля для двух целей?

Шаг 2: Анализ таблиц. Устаревшая статистика может привести к тому, что оптимизатор выберет неверный план.

Шаг 3. Запишите условия соединения в предложении FROM (например, «table1 JOIN table2 ON (table1.id = table2.id)). Это делает вас, оптимизатор и всех, кто читает ваш код, тем, что вы пытаюсь сделать. Проще переставить то, что уже организовано.

Шаг 4: Повторите Шаг 1.

Шаг 5: Мы поговорим об этом, когда вы туда доберетесь.

...