План Oracle для сравнения «B» с «B» 998x как медленный (10 г или 11 г) - PullRequest
3 голосов
/ 18 декабря 2011

Запрос на установление плохих записей по сравнению с другой таблицей.Чтобы сэкономить время, я исключаю записи, которые уже были помечены как «плохие».

Я написал запрос, но случайно проверил! = 'B' вместо! = 'B' ... запрос был выполнен за 0,203 секунды.Когда я понял свою ошибку, я изменил ее на! = 'B', но теперь выполнение запроса занимает более 200 секунд !!!

Когда я проверял планы, оптимизатор для 'b' выбирает aобъединение двух хеш-соединений.План для 'B' выбирает вложенные циклы.

Если это имеет значение, для моего теста нет записей, помеченных буквой «B».В gsu.stg_userdata ~ 18 000 записей, а в gsu.userdata_compare ~ 73 000 записей.Оба запроса дают одинаковое (и правильное) количество результатов.

Запрос:

select gstgu.global_id
from   gsu.stg_userdata gstgu
  left join gsu.userdata_compare guc
    on (gstgu.global_id = guc.global_id) or (gstgu.user_id = guc.user_id)
where  gstgu.row_check != 'b' 
   and ((-- Global IDs match, but two different Network IDs are explicitly set
         (gstgu.global_id = guc.global_id) and (guc.user_id is not null and 
                                                gstgu.user_id is not null and
                                                guc.user_id != gstgu.user_id))
         -- Network IDs match, but two different Global IDs are explicitly set
      or (guc.user_id = gstgu.user_id and (guc.global_id is not null and 
                                           gstgu.global_id is not null and
                                           guc.global_id != gstgu.global_id))
      or length(gstgu.global_id) != 8)
   and guc.global_id != '00000000';

--

План для этого sql:

                                                 Cost   Card   Bytes
SELECT STATEMENT, GOAL = ALL_ROWS                1014   1410   49350
 CONCATENATION          
  HASH JOIN                                       507    559   19565
   TABLE ACCESS FULL       GSU  STG_USERDATA      205  11144  189448
   INDEX FAST FULL SCAN    GSU  USERCOMPARE_IDX   302  16979  305622
  HASH JOIN                                       507    851   29785
   INDEX FAST FULL SCAN    GSU  USERCOMPARE_IDX   302  16979  305622
   TABLE ACCESS FULL       GSU  STG_USERDATA      205  17949  305133

Если я возьму точно такой же запрос и скажу

where  gstgu.row_check != 'B' 

, для его выполнения потребуется более 200 секунд (почти в 1000 раз больше), и план будет выглядеть так:

                                                 Cost   Card   Bytes
SELECT STATEMENT, GOAL = ALL_ROWS                 507      1      35
 NESTED LOOPS                                     507      1      35
  TABLE ACCESS FULL        GSU  STG_USERDATA      205      1      17
  INDEX FAST FULL SCAN     GSU  USERCOMPARE_IDX   302      1      18

Я схожу с ума, что дает ??

.

1 Ответ

0 голосов
/ 21 декабря 2011

добавить индекс в поле Row_check .... чаще всего эта проблема вызвана этим.

...