2010-03-16 2 views
30

Если ваша цель - проверить, существует ли строка в столбце MySQL (типа «varchar», «text», «blob» и т. Д.), Какая из следующих функций быстрее/эффективнее/лучше, и почему?Что быстрее - INSTR или LIKE?

Или, есть ли какой-либо другой метод, который соответствует одному из этих?

INSTR(columnname, 'mystring') > 0 

против

columnname LIKE '%mystring%' 
+2

Включение полнотекстового индекса поиска может быть быстрее, если ваши текстовые строки длинны – kibibu

+0

'column regexp 'mystring 'обычно быстрее, чем – Seth

+0

Ваш вопрос имеет как минимум '5' голосов за тег [tag: like-operator]. Могу я попросить вас предложить [tag: sql-like] как [синоним] (http://stackoverflow.com/tags/like-operator/synonyms)? – Kermit

ответ

45

поиск FULLTEXT абсолютно будет быстрее, так как kibibu отмечено в комментариях выше.

Однако:

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) 

В таком случае, LIKE только с суффиксом шаблона гораздо быстрее.

+10

+1 для фактического проведения эксперимента!Слишком большая производительность «мудрости» основана на инстинкте – kibibu

10

В случае «передней вилки» (т. Е. Предиката «LIKE '% ...»), как представляется, здесь, INSTR и LIKE должны выполнять примерно то же самое.

Когда подстановочный знак не «подстановочный знак», подход LIKE должен быть быстрее, если только подстановочный знак не является очень избирательным.

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

Как указано в комментарии по самому вопросу, индекс Full Text будет намного быстрее. Разница зависит от конкретного распределения слов в тексте, а также от общего размера таблицы и т. Д., Но ожидайте от двух до восьми раз быстрее, чем, возможно, в 10 раз быстрее.

Возможный недостаток использования в полнотекстовом индексе в дополнение к общим накладным расходам на создание такого индекса заключается в том, что если вы не очень осторожны в настройке этого индекса (например: определение списка стоп-слов, используя специальный синтаксис поиска для избегайте флективных форм и тому подобное ...), могут быть случаи, когда результаты, предоставленные FullText, не будут такими, как ожидалось. Например, в поисках «ПАВ» (инструмент для резки дерева) можно получить множество обращений к записям, включая глагол «видеть» в его различных сопряженных формах.
Конечно, эти функции с полным доступом к полному тексту могут быть переопределены, а также можно считать, что такие функции являются преимуществом, а не недостатком. Я просто упоминаю об этом здесь, потому что мы сравниваем это с обычным поиском подстановочных знаков.

+0

Спасибо, очень информативно. – Grekker

3

Есть немного, чтобы добавить к испытанию razzed.Но, по-видимому, с использованием regexp несет гораздо более тяжелую нагрузку обработки, в отличие от Seth указывает в своем комментарии.

Следующие тесты предполагают, что вы установили query_caching к On в my.ini

query_cache_type = 1 
query_cache_size = 64M 

Тесты

  • Тайминги показывают среднюю производительность, из трех измерений (с кэшем очищается с перерывами):

  • LIKE

    SELECT * FROM `domain_model_offers` WHERE `description` LIKE '%inform%' LIMIT 0 , 30 
    

    Начальное: 0.0035s
    кэшированных: 0.0005s

  • REGEXP

    SELECT * FROM `domain_model_offers` WHERE `description` REGEXP 'inform' LIMIT 0 , 30 
    

    Начальное значение: 0,01 с
    Cached: 0.0004s

Результат

LIKE или INSTR, безусловно, быстрее, чем REGEXP.

Несмотря на то что минимальная разница во времени кэша, вероятно, достаточна, чтобы гарантировать дальнейшее расследование.

В, вероятно, сконфигурированной системе MySQL, полнотекстовое индексирование должно всегда быть быстрее или хотя бы наравне с неиндексированным поиском. Поэтому используйте индексирование, особенно на длинных текстах человеческого языка, независимо от прерывистого кода разметки.

9

MySQL - INSTR против LOCATE против LIKE против REGEXP

Для меня INSTR и LOCATE выполнил быстрый:

# 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; 
+2

Повторяю эти тесты и вижу похожие результаты! –

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