Любое влияние производительности на Oracle для использования LIKE 'string' vs = 'string'?
Это
SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE '%some_value%';
медленнее, чем этот
SELECT * FROM SOME_TABLE WHERE SOME_FIELD = 'some_value';
но как насчет этого?
SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE 'some_value';
Мое тестирование показывает, что второй и третий примеры точно такие же. Если это правда, мой вопрос: зачем когда-либо использовать "="?
Ответы
Ответ 1
Существует явная разница, когда вы используете переменные связывания, которые вы должны использовать в Oracle, для чего угодно, кроме хранилищ данных или других операций с объемными данными.
Возьмем случай:
SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE :b1
Oracle не может знать, что значение: b1 равно "% some_value%" или "some_value" и т.д. до времени выполнения, поэтому оно будет оценивать мощность результата на основе эвристики и придумать подходящую план, который может или не может быть подходящим для различных значений: b, таких как "% A", "%", "A" и т.д.
Аналогичные проблемы могут применяться с предикатом равенства, но диапазон мощностей, который может возникнуть, гораздо легче оценивается на основе статистики столбцов или наличия уникального ограничения, например.
Итак, лично я бы не стал использовать LIKE в качестве замены для =. Оптимизатор довольно легко иногда обманывать.
Ответ 2
Просмотрите EXPLAIN PLAN для обоих. Они создают один и тот же план выполнения, поэтому в базу данных они одинаковы.
Вы использовали бы = для проверки равенства, а не для сходства. Если вы также контролируете значение сравнения, то это не имеет большого значения. Если это будет представлено пользователем, то "apple" и "apple%" дадут вам разные результаты.
Ответ 3
Если это правда, мой вопрос в том, почему когда-либо используйте "="?
Лучший вопрос: если это правда, зачем использовать "LIKE" для проверки равенства? Вы можете сэкономить, нажав клавишу shift, и все, кто читает script, могут быть смущены.
Ответ 4
Вы пробовали? Тестирование - это единственный верный способ узнать.
Как ни в стороне, ни одно из этих утверждений не обязательно вернет те же строки. Попробуйте:
insert into some_table (some_field) values ('some_value');
insert into some_table (some_fieled) values ('1some_value2');
insert into some_table (some_field) values ('some1value');
SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE '%some_value%';
SELECT * FROM SOME_TABLE WHERE SOME_FIELD = 'some_value';
SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE 'some_value';
С точки зрения ясности и избежания тонких ошибок лучше никогда не использовать LIKE, если вам не нужна эта функция. (Очевидно, что при выполнении специальных запросов это, вероятно, хорошо.)
Ответ 5
LIKE '% WHATEVER%' должен будет выполнить полное сканирование индекса.
Если процент отсутствует, он действует как равный.
Если% находится на одном конце, тогда индекс может быть сканированием диапазона.
Я не уверен, как оптимизатор обрабатывает связанные поля.
Ответ 6
like
формально то же самое, если у вас нет таких символов, как $%
и т.д., поэтому не удивительно, что он имеет такую же стоимость.
Я нахожу Дэвида Олдриджа интересным, поскольку ваше приложение должно использовать переменные связывания. С помощью like '%foobar'
вы не можете использовать порядок в индексе. Если запрос предварительно скомпилирован, это приведет к большему индексу или полному сканированию.
Кроме того, я считаю это опасным, так как это может привести к инъекциям SQL и странным ошибкам (например, если есть пользователь, названный john, хакер может создать пользователя с именем 'joh$'
и попытаться войти в систему)
зачем рисковать? '='
понятнее и не имеет ни одной из этих проблем.