MySQL сортировка по нескольким таблицам занимает очень много времени - PullRequest
1 голос
/ 19 мая 2011

У меня есть таблица с объектами и связанными таблицами object_info, object_theme (категория), местоположения и владельцы объектов.

Я хочу показать сначала все объекты от владельцев объектов с более высоким приоритетом, а затем все остальные. Поэтому мой запрос выглядит примерно так:

SELECT 
   (...)
FROM objects
INNER JOIN object_info ...
INNER JOIN objectowner_info ...
INNER JOIN locations ...
WHERE object_active = 1
  AND object_owner_active = 1
ORDER BY object_owner_priority DESC,
         object_price ASC
   LIMIT 0, 10

Как вы можете видеть, я выбираю все объекты и даю объекты от владельцев объектов с более высоким приоритетом. А потом сортировка от самой низкой цены вверх. Но большую часть времени этот запрос очень медленный.

Каковы лучшие шаги для оптимизации этого запроса? Я пробовал все виды индексов, но узкое место, кажется, сортировка. Когда я убираю это, запрос в порядке скорости.

(Обратите внимание, что я не присоединился к темам (категориям), я думаю реализовать это по-другому из-за отношений 1: n, которые вам также понадобятся для группировки результата, и это кажется ужасно медленным. Все другие таблицы, упомянутые в соединении, имеют отношение 1: 1.).

Для сравнения: запрос без обоих столбцов при сортировке занимает 0,0011 секунды. Упомянутый выше с обеими колонками 0.8779. Но в зависимости от нагрузки это может занять даже секунды.


ОБЪЯСНИТЬ с сортировкой:

id  select_type     table   type    possible_keys                                       key                 key_len     ref             rows    Extra
1   SIMPLE          o       ALL     PRIMARY,fk_object_user,fk_object_city,type active   NULL                NULL        NULL            63773   Using where; Using temporary; Using filesort
1   SIMPLE          ooi     ref     fk_objectowner_id                                   fk_objectowner_id   4           o.object_user   1       Using where
1   SIMPLE          oo      eq_ref  PRIMARY,id_and_status                               PRIMARY             4           o.object_user   1       Using where
1   SIMPLE          l       eq_ref  PRIMARY                                             PRIMARY             4           o.object_city   1       Using where
1   SIMPLE          oi      ref     fk_info_lang,fk_info_object,lang_object             fk_info_object      3           o.object_id     1       Using where

ОБЪЯСНЯТЬ без сортировки:

id  select_type     table   type    possible_keys                                       key                 key_len     ref             rows    Extra
1   SIMPLE          o       ALL     PRIMARY,fk_object_user,fk_object_city,type active   NULL                NULL        NULL            63773   Using where
1   SIMPLE          ooi     ref     fk_objectowner_id                                   fk_objectowner_id   4           o.object_user   1   Using where
1   SIMPLE          oo      eq_ref  PRIMARY,id_and_status                               PRIMARY             4           o.object_user   1   Using where
1   SIMPLE          l       eq_ref  PRIMARY                                             PRIMARY             4           o.object_city   1   Using where
1   SIMPLE          oi      ref     fk_info_lang,fk_info_object,lang_object             fk_info_object      3           o.object_id     1   Using where

Ответы [ 2 ]

0 голосов
/ 30 мая 2011

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

0 голосов
/ 19 мая 2011

Определите индексы для object_owner_priority и object_price и измените предложение where на что-то вроде:

WHERE object_active + 0 = 1
  AND object_owner_active + 0 = 1

Если повезет, это должно сработать. Если вы определили индексы для object_active или object_owner_active, рассмотрите возможность их удаления.

...