2016-06-20 2 views
4

На вопрос this question что я спросил, на днях я получил следующий комментарий.Почему функции на столбцах препятствуют использованию индексов?

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

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

Не могли бы вы объяснить, почему это происходит, и, возможно, стратегии для его устранения?

+0

Существуют функциональные индексы, по крайней мере, в Oracle. Это может быть одно из исключений здесь и там :-) –

ответ

2

Индекс в его самой базовой форме - это только отсортированные данные столбца, что позволяет легко найти какую-то ценность. Например, учебник может иметь страницы в некотором порядке, но затем иметь индекс в обратном для всех условий. Как вы можете видеть, данные предварительно вычисляются/сортируются и сохраняются в отдельной области.

Когда вы применяете функцию к столбцу и пытаетесь совместить/фильтровать на основе результата, индекс больше не является полезным. Давайте снова рассмотрим наш пример книги и скажем, что функция, которую мы применяем, является обратной величине термина (так reverse('integral') становится 'largetni'). Вы не найдете это значение в индексе, поэтому вам нужно взять все условия, поместить их через функцию и только затем сравнить. Все время запроса. Первоначально мы могли пропустить поиск по i, затем in, затем int и т. Д., Что упростило поиск термина, поэтому функция сделала все гораздо медленнее.

Если вы часто запрашиваете эту функцию, вы можете сделать индекс с reverse(term) раньше, чтобы ускорить поиск. Но, не делая этого явно, он всегда будет медленным.

2

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

2

Вот хорошее объяснение того, почему это происходит (это конкретная статья SQL Server, но, вероятно, относится и к другим системам SQL RDBMS):

https://www.mssqltips.com/sqlservertip/1236/avoid-sql-server-functions-in-the-where-clause-for-performance/

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

2

Рассмотрим крайний пример. Предположим, что вы ищете строку с использованием криптографической хэш-функции, например HASH(email_address) = 0x123456. База данных имеет индекс, построенный на email_address, но теперь вы просите его искать данные по HASH(email_address), которых у него нет. Это может по-прежнему использовать индекс, но в итоге ему придется посмотреть на каждую запись индекса для email_address и посмотреть, соответствуют ли HASH(email_address). Если вам нужно будет сканировать полный индекс, он может просто просто сканировать полную таблицу, чтобы не было необходимости возвращаться туда и обратно, получая отдельные местоположения строк.

Смежные вопросы