Любое влияние производительности на 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$' и попытаться войти в систему)

зачем рисковать? '=' понятнее и не имеет ни одной из этих проблем.