Избегайте применения функции к столбцу индекса - PullRequest
0 голосов
/ 18 апреля 2019

Мне нужно отфильтровать данные, которые превышают определенную длину, но столбец, содержащий данные, является индексированным столбцом. Если я применяю функцию к столбцу, я теряю преимущество индекса.

Я не могу создать новый индекс или изменить столбец, так как я не являюсь администратором базы данных. Я бы предпочел не сбрасывать данные после факта.

Я знаю несколько способов фильтрации столбца, но все будут использовать какую-то функцию.

select
table.name
from 
table
where
length(table.name)>12
;

Поле table.name не имеет значения null.

Ответы [ 2 ]

1 голос
/ 19 апреля 2019

Если я применяю функцию к столбцу, я теряю преимущество индекса.

Ах, а в чем выгода индекса?

Рассмотрим эти два значения:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

Они оба длиннее 12 символов? Да. Могут ли они быть смежными в индексе? Конечно, нет. Поэтому единственный способ для Oracle использовать индекс для нахождения этих значений - выполнить полное быстрое сканирование индекса и оценить длину каждой записи. Теперь Oracle может это сделать, но стоит ли это делать?

Ваш опубликованный запрос выбирает просто name. В комментарии вы говорите, что name не обнуляется. В этом случае для Oracle было бы эффективно использовать индекс, поскольку нет необходимости читать записи таблицы: индекс имеет достаточно информации для удовлетворения запроса.

Тем не менее.

В этом комментарии вы также говорите:

запрос не так прост

Если ваш фактический запрос включает в себя другие столбцы в проекции, то для получения этих значений база данных должна посетить таблицу. В этот момент вступает в силу эмпирическое правило для индексированного чтения: если результирующий набор запроса превышает 1-2% всех строк в таблице, более эффективно выполнить полное сканирование таблицы, чем использовать индекс. Таким образом, количество записей в таблице становится уместным, и особенно доля записей, где length(name) > 12. Если 99% записей имеют короткие имена, то, вероятно, еще эффективнее будет полное быстрое сканирование индекса. Но если он будет использовать только 90% индекса, это может привести к снижению производительности.

Аналогичным образом, если ваш фактический запрос применяет дополнительные критерии в предложении WHERE, может быть более эффективно выполнить полное сканирование таблицы (поскольку базе данных необходимо считывать записи для оценки этих фильтров), чтобы использовать другой индекс, если есть является подходящим.

Таким образом, хотя индекс будет полезен для игрушечного запроса, который вы разместили в своем вопросе, он может не помочь с вашим реальным запросом и даже может привести к неоптимальному пути доступа.

это индивидуальная ситуация в зависимости от сложности запроса?

Да. Ответ всегда, это зависит . Вот почему профессионалы по настройке баз данных могут брать с них полную плату за консультацию. Если вы не предоставите полный запрос, лучшее, что мы можем сделать, - это , укажите вам на этот пост, в котором объясняется, как задавать вопросы по настройке производительности , и желаю вам удачи.

1 голос
/ 19 апреля 2019

Если столбец NOT NULL, Oracle может ответить на запрос, используя полное сканирование индекса.Потребуется прочитать каждую строку в индексе, чтобы найти только те строки, длина которых превышает 12. Если индекс меньше таблицы, это быстрее, чем полное сканирование.

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

Нет способа обойти это без добавления более подходящего индекса илив противном случае изменение схемы базы данных.

...