Можно ли индексировать все поля в этом запросе mysql? - PullRequest
4 голосов
/ 08 ноября 2011

У меня есть этот запрос MySQL, и я не уверен, каковы последствия индексации всех полей в запросе. Я имею в виду, нормально ли индексировать все поля в операторе CASE, операторе соединения и инструкции где? Есть ли какие-либо последствия для производительности полей индексации?

SELECT roots.id as root_id, root_words.*,
CASE 
WHEN root_words.title LIKE '%text%' THEN 1
WHEN root_words.unsigned_title LIKE '%normalised_text%' THEN 2
WHEN unsigned_source LIKE '%normalised_text%' THEN 3
WHEN roots.root LIKE '%text%' THEN 4
END as priorities
FROM  roots INNER JOIN root_words ON roots.id=root_words.root_id
WHERE (root_words.unsigned_title LIKE '%normalised_text%') OR (root_words.title LIKE '%text%')
OR (unsigned_source LIKE '%normalised_text."%') OR (roots.root LIKE '%text%') ORDER by priorities

Кроме того, как я могу еще улучшить скорость запроса выше?

Спасибо!

Ответы [ 4 ]

5 голосов
/ 08 ноября 2011
  1. Вы индексируете столбцы в таблицах, а не в запросах.

  2. Ни один из указанных вами критериев поиска не сможет использовать индексы (посколькуусловия поиска начинаются с символа подстановки).

  3. Необходимо убедиться, что столбец id проиндексирован, чтобы ускорить JOIN.(Предположительно, он уже проиндексирован как ПЕРВИЧНЫЙ КЛЮЧ в одной таблице и ВНЕШНИЙ КЛЮЧ в другой).

Чтобы ускорить этот запрос, вам потребуется использовать полнотекстовый поиск.Добавление индексов не ускорит этот конкретный запрос и будет стоить вам времени на INSERT, UPDATE и DELETE.

2 голосов
/ 08 ноября 2011

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

В этом конкретном запросе единственный индекс, который может помочь, будет в вашем предложении JOIN, в полях roots.id и root_words.root_id.

Ни одна из проверок в вашем предложении WHERE не может быть проиндексирована из-за ведущего '%'. Это заставляет SQL сканировать каждую строку в этих таблицах на предмет совпадения значений.

Если вам удастся удалить ведущий '%', вы бы выиграли от использования индексов в этих полях ... если нет, вам следует заняться реализацией полнотекстового поиска ; но будьте осторожны, это не тривиально.

2 голосов
/ 08 ноября 2011

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

1 голос
/ 08 ноября 2011

Индексирование не поможет при использовании вместе с LIKE '%something%'.

Это похоже на поиск слов в словаре, в которых где-то есть ae.Словарь (или Индекс в данном случае) организован на основе первой буквы слова, затем второй буквы и т. Д. В нем нет механизма для помещения всех слов с ae в них близко друг к другу.Вы по-прежнему читаете весь словарь от начала до конца.


Индексация полей, используемых в предложении CASE, скорее всего, вам не поможет.Индексирование помогает легко находить записи в таблице.Предложение CASE касается обработки найденных вами записей, а не их нахождения.


Оптимизаторы также могут бороться с оптимизацией нескольких несвязанных OR условий, таких как ваша.,Оптимизатор пытается сузить объем усилий, необходимых для выполнения вашего запроса, но это трудно сделать, когда несвязанные условия могут сделать запись приемлемой.


В целом ваш запросвыиграли бы от индексов roots(root_id) и / или roots(id), но не намного больше.

Если бы вы проиндексировали дополнительные поля, две основные затраты:
- увеличение времени записи (вставка(обновить или удалить) из-за дополнительных индексов для записи в
- Увеличение занимаемого места на диске

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