Что быстрее-INSTR или LIKE?
Если ваша цель состоит в том, чтобы проверить, существует ли строка в столбце MySQL (типа "varchar", "text", "blob" и т. д.), который из следующих быстрее / эффективнее / лучше использовать, и почему?
или есть какой-то другой метод, который превосходит любой из них?
INSTR( columnname, 'mystring' ) > 0
vs
columnname LIKE '%mystring%'
4 ответов
полнотекстовый поиск абсолютно будет быстрее, как отметил кибибу в комментариях выше.
:
mysql> select COUNT(ID) FROM table WHERE INSTR(Name,'search') > 0;
+-----------+
| COUNT(ID) |
+-----------+
| 40735 |
+-----------+
1 row in set (5.54 sec)
mysql> select COUNT(ID) FROM table WHERE Name LIKE '%search%';
+-----------+
| COUNT(ID) |
+-----------+
| 40735 |
+-----------+
1 row in set (5.54 sec)
в моих тестах, они выполняют точно такую же. Они оба нечувствительны к регистру, и обычно они выполняют сканирование полной таблицы, общее нет - нет при работе с высокопроизводительным MySQL.
Если вы не выполняете поиск префикса в индексированном столбце:
mysql> select COUNT(ID) FROM table WHERE Name LIKE 'search%';
+-----------+
| COUNT(ID) |
+-----------+
| 7 |
+-----------+
1 row in set (3.88 sec)
в этом случае, как только суффикс подстановочный знак намного быстрее.
MySQL - INSTR vs найти vs как vs и
для меня INSTR и найти выполняется быстрее всего:
# 5.074 sec
SELECT BENCHMARK(100000000,INSTR('foobar','foo'));
# 5.086 sec
SELECT BENCHMARK(100000000,LOCATE('foo','foobar'));
# 8.990 sec
SELECT BENCHMARK(100000000,'foobar' LIKE '%foo%');
# 14.433 sec
SELECT BENCHMARK(100000000,'foobar' REGEXP 'foo');
# 5.5.35-0ubuntu0.12.10.2
SELECT @@version;
в случае " переднего wilcard "(т. е. "как"%..."предикат), как это, по-видимому, имеет место здесь,INSTR и LIKE должны выполнять примерно то же самое.
когда Джокер не "передний подстановочный знак", подобный подход должен быть быстрее, если подстановочный знак не очень избирательный.
причина почему тип подстановочного знака и его избирательность имеют значение это предикат с INSTR () будет систематически результат сканирования таблицы (SQL не может делать никаких предположений о семантике INSTR), в результате чего SQL может использовать свое понимание семантики подобного предиката, чтобы, возможно, использовать индекс, чтобы помочь ему протестировать только уменьшенный набор возможных совпадений.
Как предложено в комментарии к самому вопросу,полнотекстовый индекс будет намного быстрее. Разница зависит от конкретного распределения слов в тексте, а также общего размера таблицы и т. д. но ожидайте что-нибудь от вдвое быстрее, может быть, в 10 раз быстрее.
возможный недостаток использования в полнотекстовом индексе, в дополнение к общим накладным расходам для создания такого индекса, заключается в том, что, если вы не очень осторожны в настройке этого индекса (например, определение списка стоп-слов, используя конкретный синтаксис поиска, чтобы избежать инфлективных форм и тому подобное...), могут быть случаи, когда результаты, предоставленные FullText, не будут ожидаемыми. Например, поиск " пилы "(инструмента рубить дрова), можно получить много хитов для записей, включая глагол "видеть", в его различных спрягаемых формах.
Конечно, эти лингвистические функции полнотекстовых индексов обычно можно переопределить, а также можно считать, что такие функции фактически являются преимуществом, а не недостатком. Я просто упоминаю об этом здесь, так как мы сравниваем это с простой поиск по шаблону.
мало что можно добавить к тесту раззеда. Но, по-видимому, используя regexp
нести гораздо тяжелее нагрузки, как сет указывает в своем комментарии.
следующие тесты предполагают, что вы установили query_caching
до On
в моем.ini
query_cache_type = 1
query_cache_size = 64M
тесты
тайминги показывают среднюю производительность, из трех измерений (с очищенным кэшем периодически):
-
как
SELECT * FROM `domain_model_offers` WHERE `description` LIKE '%inform%' LIMIT 0 , 30
начальный: 0.0035 s
кэширование: 0.0005 s -
REGEXP
SELECT * FROM `domain_model_offers` WHERE `description` REGEXP 'inform' LIMIT 0 , 30
начальный: 0.01 s
кэширование: 0.0004 s
результат
LIKE
или INSTR
определенно быстрее, чем REGEXP
.
хотя и минимальная, разница во времени кэша, вероятно, достаточна для дальнейшего расследования.
в Вероятно настроенной системе MySQL полнотекстовое индексирование обычно должно быть всегда быстрее или, по крайней мере, на одном уровне с неиндексированным поиском. Поэтому используйте индексацию, особенно на длинных текстах на человеческом языке, независимо от прерывистого кода разметки.