Как оптимизировать запрос с несколькими% - PullRequest
0 голосов
/ 13 февраля 2020

Пожалуйста, помогите мне оптимизировать мой Mysql запрос ниже

SELECT * FROM `ticket` WHERE `ticket_id` LIKE '%wm%33%' LIMIT 0,1000

таблица не имеет полнотекстового индекса, и я боюсь, что предоставление столбцу полнотекстового индекса будет стоить времени, когда таблица нужно быть всегда на

Ответы [ 2 ]

0 голосов
/ 13 февраля 2020
WHERE `ticket_id` LIKE '%wm%33%'

можно заменить на

WHERE LOCATE('wm', ticket_id) < LOCATE('33', ticket_id) (см. Ниже)

Я думаю, что это дешевле.

PS. Никакое индексирование не может помочь улучшить производительность поиска ...


Barmar : LOCATE() возвращает 0, если строка не найдена, поэтому это будет вернуть строки, которые не содержат wm. Измените его на

LOCATE('wm', ticket_id) BETWEEN 1 AND LOCATE('33', ticket_id)

Это правда.

0 голосов
/ 13 февраля 2020

Если вы не хотите использовать полнотекстовый индекс, и я бы посоветовал вам провести сравнительный анализ, чтобы определить, не влияет ли индекс на производительность вставки, вы можете реструктурировать свои данные, чтобы исключить необходимость в такого рода поисках.

Мы не знаем, что в ticket_id, но ясно, что у него какая-то структура. Вместо анализа и поиска этого объединения лучше разбить его на отдельные части и объединить.

Чтобы использовать аналогичный пример, давайте рассмотрим адреса электронной почты. Что делать, если вы хотите искать пользователей, чьи адреса электронной почты для gmail.com? Наивный способ сделать это будет ...

create table users (
  id serial primary key,
  email varchar(255) not null unique
);

select * from users
where email like '%@gmail.com'

Есть проблема с производительностью. Также существует проблема соответствия user@subdomain.gmail.com. like '%gmail.com' приносит свои проблемы, он будет соответствовать person@thingmail.com.

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

create table users (
  id serial primary key,
  email varchar(255) not null unique,
  domain varchar(255) as (
    substring_index(substring_index(email, '@', -1), '.', -2)
  ),

  index(domain)
);

Теперь сопоставление домена - это простая индексированная проверка на равенство.

select * from users
where domain = 'gmail.com'

Я полагаю, вы можете сделать что-то подобное для своего ticket_id. Стоит ли это усилий, требует некоторого тестирования, а также учета сложности: полнотекстовый индекс проще и гибче.

dbfiddle

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