powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / не подхватывается индекс
17 сообщений из 17, страница 1 из 1
не подхватывается индекс
    #32171468
Vladimir_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oracle 8.1.7 win2000sp3

Есть табличка
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
ACCOUNT_LIST
( ACCOUNT_ID      NUMBER( 38 ) not null,
  CUSTOMER_ID     CHAR( 7 ),
  N               CHAR( 1 ),
  SUB_ACCOUNT     CHAR( 2 ),
  CURRENCY_ID     CHAR( 4 ),
  BRANCH_ID       CHAR( 3 ),
  ...

и есть уникальный индекс
Код: plaintext
unique (BRANCH_ID,CUSTOMER_ID,N,SUB_ACCOUNT,CURRENCY_ID)

пишу запрос:
Код: plaintext
1.
2.
3.
4.
5.
6.
select Account_id   
  from Account_List  
 where Branch_id = '664'
   and Customer_id = nvl('9900135',Customer_id)  
   and N = nvl('0',n)
   and Sub_Account = nvl('02',Sub_Account)
   and Currency_id = nvl('USD ',Currency_id)

при любом режиме оптимизатора сканируется уникальный индекс
немного модифицируем
Код: plaintext
1.
2.
3.
4.
5.
6.
select Account_id   
  from Account_List  
 where Branch_id = nvl('664',Branch_id)
   and Customer_id = nvl('9900135',Customer_id)  
   and N = nvl('0',n)
   and Sub_Account = nvl('02',Sub_Account)
   and Currency_id = nvl('USD ',Currency_id)

и оптимизатор падает в панику : TABLE ACCESS FULL
обьясните пожалуйста, почему так происходит
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171478
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
and Customer_id = nvl('9900135',Customer_id)  
   and N = nvl('0',n)
   and Sub_Account = nvl('02',Sub_Account)
   and Currency_id = nvl('USD ',Currency_id)


Для чего ты используешь NVL, когда у тебя конкретные значения указаны и явно не NULL?
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171489
Фотография killed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Юникальный индекс из пяти значений - это слишком много...
2. План похоже меняется, поскольку оптимизатор не может гарантировать результат через индексный доступ в случае, когда во всех столбцах индекса будет NULL. Т.е. в данном случае думаю, что оптимизатор не учитывает, что в nvl'ax стоят литералы
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171490
Фотография killed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
можешь проверить - в втором примере добавить в кляузу where условие
and branch_id is not NULL
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171492
Vladimir_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в реальной ситуации там переменные, передаваемые через процедуру в качестве параметров. Я просто пытался промоделировать данный запрос и не совсем понимаю, как влияет nvl именно для Branch_id. Для всех остальных полей присутствие nvl никак не сказывается на выборе оптимизатора.
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171496
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я думаю, что у него и в первом то случае where Branch_id = '664' индекс подхватывается только для столбца Branch_id, благо он первый в индексе.
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171498
Vladimir_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to killed
пробовал, не помагает.
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171502
Vladimir_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to softbuilder
похоже на правду, т.е. происходит RANGE SCAN по первой составляющей индекса. Если убираю все nvl, то происходит UNIQUE SCAN.
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171506
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если CHAR на VARCHAR2 поменять - тоже самое получается?
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171519
Vladimir_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to softbuilder
к сожалению я не могу менять структуру базы.
А чем мотивируется данная замена в этой ситуации?
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171524
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мотивировка в следующем:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SQLWKS> select dump('664'), dump(nvl('664','665')) from dual
      2 > 
      3 > 
DUMP('664')            DUMP(NVL('664','665')
 ---------------------- ---------------------
 
Typ= 96  Len= 3 :  54 , 54 , 52  Typ= 1  Len= 3 :  54 , 54 , 52 
Выбрана  1  строка.
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171527
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Table  21  Built-In Datatype Summary

 1  VARCHAR2( size) Variable-length character string having maximum
length size bytes. Maximum size is  4000 , and
minimum is  1 . You must specify size for
VARCHAR2.

 96  CHAR( size) Fixed-length character data of length size bytes.
Maximum size is  2000  bytes. Default and
minimum size is  1  byte.
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171546
va_kochnev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Индекс будет подцепляться толкько тогда, когда индексированный столбец указан с одной стороны выражения и по другую сторону выражения нет столбцов этой же таблицы.
Т.е. при branch_id='2134' индекс может быть задействован, а при
branch_id=branch_id уже индекс работать не будет.
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171553
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С моей стороны, это только предположение.
Создай копию этой таблицы с индексами, только с полями VARCHAR2 и проверь на ней. Совсем не обязательно заполнять всеми данными из рабочей таблицы.
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171558
Vladimir_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to va_kochnev
Спвсибо, очень похоже на правду
если пишу
Код: plaintext
BRANCH_ID = nvl('664','655')

то индекс подхватывается. nvl получается тут ни при чём.
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32171644
va_kochnev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если уж непременно хочется, чтобы работало по индексу то выражение
Branch_id = nvl('664',Branch_id)
можно преобразовать в
branch_id between nvl(<параметр>,<минимально возможное значение branch_id>) and nvl(<параметр>,<максимально возможное значение branch_id>)
...
Рейтинг: 0 / 0
не подхватывается индекс
    #32172029
I did not have my coffee yet, so can someone explain me what is the reason (unless it is pure experiment) for expressions like nvl('9900135',Customer_id) which always results in '9900135'. Another words, condition Customer_id = nvl('9900135',Customer_id) is nothing more but a very twisted way to say Customer_id = '9900135'. So if you want to test optimizer IQ, it obviously did not pass this one. Otherwise it would realize that NVL of a constant is a constant itself and therfore would use index UNIQUE SCAN. However, it is smart enough to know that NVL, in general, can result in its second operand which in this case is NULLABLE Customer_id column. As a result, it can not use UNIQUE SCAN and either decides todo RANGE SCAN (by Branch_id = '664') or FULL SCAN if statistics suggests so (or if it is "because I feel like it" we all know optimizer often has a mind of its own :-) ).

Artist formerly known as SY.
P.S. Another early morning surprize. Someone stole my identity and registered as SY. So if you see some nonsense from SY - it is not me, but if is something smart, yes it is me :-).
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / не подхватывается индекс
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]