This Might Be Useful

Как заставить JOIN в MySQL нормально использовать индексы и максимально ускорить выполнение запросов

Несколько раз натыкался на эту проблему, но только сегодня полноценно ее решил. Проблема проста: есть запрос с несколькими JOIN'ами. При выполнении запроса толком не используются индексы. В результате все ужасно тормозит.
Запрос примерно такой:

SQL:
  1. SELECT `a`.*, `b`.*
  2. FROM `a` LEFT JOIN `b` ON `a`.`field1` = `b`.`field2`
  3. WHERE `b`.`field3` = "something"
  4. ORDER BY `a`.`field4`

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

  1. Создать индекс по каждому из полей, используемых в WHERE и JOIN. Отдельно по каждому.
  2. Убедиться, что в WHERE указано максимально жесткое условие дабы сократить диапазон выборки.
  3. А теперь - внимание! Убедиться, что у `a`.`field1` и `b`.`field2` одинаковый collation!

Комментарий по последнему пункту: В моем случае у одного поля был latin1_swedish_ci, у второго - utf8_general_ci. Вроде как по данным выходило правильно. Но запрос работал очень медленно, порядка 3 секунд (использовались три таблицы с большим количеством записей - ~100,000, ~30,000 и ~3,000). После применения пункта номер один и особенно пункта номер три запрос стал выполняться за 0.1 (одну десятую!) секунды.

· Сборка MySQL, Apache и PHP со всеми необходимыми расширениями
· Ускорение копирования и перемещения файлов в Windows Vista
· Реализация аналога LIMIT из MySQL в MS SQL
· Создание загрузочного USB
· Сборка нового ядра для Ubuntu Linux

- Коментировать
- Trackback

8 Responses to “Как заставить JOIN в MySQL нормально использовать индексы и максимально ускорить выполнение запросов”


  1. venil Says:

    0.1 это не одна сотая, это одна десятая секунды

    сравнение полей с разным collation делать нельзя, MySql выдаст ошыбку, не далее как сегодня утром с этим столкнулся

  2. Filosoff Says:

    venil @ 30.07.2008, 16:58 #

    0.1 это не одна сотая, это одна десятая секунды

    опечатался

    venil @ 30.07.2008, 16:58 #

    сравнение полей с разным collation делать нельзя, MySql выдаст ошыбку, не далее как сегодня утром с этим столкнулся

    вообще-то можно. и работает. и join по ним можно. десятки раз проверено. последний раз - сегодня. только тормозит. потому и написал заметку.

  3. venil Says:

    Filosoff @ 30.07.2008, 17:33 #

    вообще-то можно. и работает. и join по ним можно. десятки раз проверено. последний раз - сегодня. только тормозит. потому и написал заметку.

    вот что я получаю:

    venil @ 31.07.2008, 10:16 #

    Error Code : 1267
    Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_general_ci,IMPLICIT) for operation '='
    (0 ms taken)

    версия MySql: 5.0.51a-3ubuntu5.1

  4. Filosoff Says:

    никогда такого не встречал, если честно. хотя это возможное поведение...

  5. venil Says:

    я немного погуглил по этому поводу:

    venil @ 31.07.2008, 11:25 #

    You can join a unicode and a non-unicode table. You cannot join two unicode tables with different collations or two non-unicode tables with different charset or collation.

  6. Filosoff Says:

    ага, ясно. буду знать :)

  7. Киря Робски Says:

    А есть, какая нибудь альтернатива? ;)

  8. LeX Says:

    спасибо

Leave a Reply

code