Что быстрее-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 полнотекстовое индексирование обычно должно быть всегда быстрее или, по крайней мере, на одном уровне с неиндексированным поиском. Поэтому используйте индексацию, особенно на длинных текстах на человеческом языке, независимо от прерывистого кода разметки.