Mysql Улучшение производительности поиска с использованием подстановочных знаков (%%) - PullRequest
11 голосов
/ 06 мая 2011

Ниже приведен запрос, который я использую для поиска человека по электронной почте

  SELECT *
    FROM phppos_customers
    JOIN phppos_people ON phppos_customers.person_id = phppos_people.person_id
   WHERE deleted = 0
     AND email LIKE '%f%'
ORDER BY email ASC

Ускорит ли добавление индекса по электронной почте запрос?

Ответы [ 6 ]

17 голосов
/ 06 мая 2011

Нет, потому что MySQL не сможет использовать индекс, когда у вас есть начальный шаблон.Если вы изменили свой LIKE на «f%», он сможет использовать индекс.

7 голосов
/ 06 мая 2011

Нет, Mysql не будет использовать индекс, поскольку аргумент LIKE (%f%) начинается с символа подстановки %. Если он начинается с константы, будет использован индекс.

Подробнее: 7.5.3. Как MySQL использует индексы

5 голосов
/ 06 мая 2011

Подстановочные знаки в левой части операции LIKE гарантируют, что индекс, если он существует в столбце email, не может быть использован.

Полнотекстовый поиск (FTS) является предпочтительным синтаксисом для поискастроки в тексте через SQL. MySQL имеет встроенную функциональность FTS с использованием синтаксиса MATCH / AGAINST (требуется таблица для использования механизма MyISAM для v.5.5 и ниже. InnoDB FTS поддерживается в v.5.6 +) :

  SELECT c.*, p.*
    FROM PHPPOS_CUSTOMERS c
    JOIN PHPPOS_PEOPLE p ON p.person_id = c..person_id
   WHERE deleted = 0
     AND MATCH(email) AGAINST('f')
ORDER BY email 

Но есть сторонние технологии FTS, такие как Sphinx.

4 голосов
/ 11 декабря 2014

В своем посте я подробно описываю технику, которая позволяет использовать индекс с LIKE для быстрого %infix% поиска , за счет некоторыхдополнительное хранилище:

https://stackoverflow.com/a/22531268/543814

Пока строки относительно невелики, требования к хранилищу обычно приемлемы.

По данным Google, средний адрес электронной почтыдлиной 25 символов.Это увеличивает требуемое хранилище в среднем в 12.5 раз и обеспечивает быстрый индексированный поиск в ответ.(См. Мой пост для расчетов.)

С моей точки зрения, если вы храните 10 000 адресов электронной почты, вы должны хорошо хранить (эквивалентно) около 100 000 адресов электронной почты,тоже.Если это то, что нужно, чтобы позволить вам использовать индекс, это кажется приемлемым компромиссом.Зачастую дисковое пространство дешевое, а неиндексированные поиски недоступны.

Если вы решите воспользоваться этим подходом, я предлагаю ограничить длину ввода адресов электронной почты 64 символами.Этим редким (или злоумышленникам) адресам электронной почты такой длины потребуется в 10 * 10 раз больше обычного хранилища.Это дает вам:

  1. Защита от злоумышленника, пытающегося заполнить вашу базу данных, поскольку эти данные все еще не очень впечатляющие.
  2. Ожидание того, что большинство адресов электронной почты являютсяв любом случае не такой длины.

Если вы считаете 64 символами слишком жесткими, используйте вместо этого 255, чтобы коэффициент увеличения хранилища в худшем случае составил 127.5.Смешной?Возможно.Скорее всего?Нет. Быстро?Очень.

1 голос
/ 06 мая 2011

Вы не сможете сделать это быстрее с LIKE, как все говорят (о % в начале), но вы можете немного улучшить его, присоединившись после того, как сначала отфильтруете своих людей.

SELECT *
  FROM (SELECT * 
          FROM `phppos_customers`
         WHERE `deleted` = 0
           AND  `email`  LIKE '%f%') `t_customers`
  JOIN `phppos_people` ON `t_customers`.`person_id`=`phppos_people`.`person_id`
 ORDER BY `email` asc
0 голосов
/ 26 мая 2018

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

Так что, если у вас есть в слове db слово «slibro» и вы хотите выполнить поиск «% libro», созданный обратный столбец будет содержать «orbils», а поиск будет «orbil%».

Если вам нравится мое решение, пожалуйста, проверьте мой профиль и пришлите мне BTC, спасибо:)

PS: Но нет решения, как сделать быстрый полный поиск по шаблону "% x%", хотя:).

...