Производительность REGEXP (сравните с "LIKE" и "=") - PullRequest
17 голосов
/ 16 ноября 2011

Я использую MySQL. Я задал вопрос о том, как запросить в базе данных совпадение одного слова здесь .

  • Есть ответ, который предлагает мне использовать REGEXP '[[:<:]]word[[:>:]]'

    Это хороший ответ, однако я не уверен, как это REGEXP '[[:<:]]word[[:>:]]' с точки зрения производительности? Если у меня есть большая таблица, это повредит производительности моего приложения?

Например, сравнить с операцией =, например, WHERE column_name='value', операция REGEXP намного медленнее, чем = для большой таблицы?

  • Есть еще один ответ, который предложил мне использовать LIKE, но я думаю, что это нехорошо с точки зрения производительности.

    Затем я гуглил и нашел статью , в которой говорится, что использование LIKE даже быстрее , чем REGEXP. Я запутался, каким способом я должен использовать для запроса совпадения одного слова в большой таблице ...

Могу ли я сказать, = - самая быстрая операция, тогда LIKE, а REGEXP - самая бедная с точки зрения производительности?

Ответы [ 2 ]

37 голосов
/ 08 декабря 2011

Относительно регулярного выражения

Регулярное выражение может никогда использовать индекс в MySQL.
= будет использовать индекс, если:

  • для столбца объявлен индекс;
  • значения в столбце имеют достаточную мощность (если совпадает более +/- 20% строк, MySQL не будет использовать индекс, поскольку вв этом случае полное сканирование таблицы выполняется на быстрее );
  • Никакие другие индексы в той же таблице не подходят лучше (MySQL может использовать только один индекс на таблицу на каждый поднабор);

Учитывая эти и некоторые другие более эзотерические предостережения, = сравнение на намного быстрее, чем регулярное выражение.

Относительно того, как

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

SELECT * FROM t WHERE a LIKE 'abc'   <<-- (case insensitive `=`) can use an index
SELECT * FROM t WHERE a LIKE 'abc%'  <<-- can use an index
SELECT * FROM t WHERE a LIKE 'a%'    <<-- can use an index, depending on cardinality
SELECT * FROM t WHERE a LIKE '%a%'   <<-- cannot use an index
SELECT * FROM t WHERE a LIKE '_agf'  <<-- cannot use an index

Производительность like при использовании индекса очень близка к = (при условии, что возвращается столько же строк).

0 голосов
/ 08 декабря 2011

Существует еще один способ поиска данных: Полнотекстовый поиск . Его можно использовать, когда like, = недостаточно (выполнение времени), а с другой стороны, Sphinx, Lucene слишком мощный.

Чтобы использовать его, вы должны создать полнотекстовый индекс для столбца и запросить его. Если вы будете использовать его, пожалуйста, обратите внимание на системные переменные ft_min_word_len, ft_max_word_len, которые уменьшают минимальный / максимальный размер слова.

Надеюсь, это поможет.

На остальную часть вашего вопроса ответил @ Johan.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...