Улучшить это возможно 5 объединяет предложение SQL - PullRequest
0 голосов
/ 25 октября 2009

Я использую MySQL 5, и мне нужно сделать это предложение, чтобы получить результаты. Это первая попытка, когда я думаю об этом. Я знаю, что есть несколько способов улучшить его, но сначала я хочу узнать ваше мнение:

SELECT p.id, p.image, p.lat, p.lng, 
       p.category_id, p2.title, p2.description, c2.name
FROM place p
LEFT JOIN place_translation p2 ON p.id = p2.id
LEFT JOIN trip_place t ON p.id = t.place_id
LEFT JOIN category c ON p.category_id = c.id
LEFT JOIN category_translation c2 ON c.id = c2.id
WHERE c.root_id =1
AND c2.lang =  'en'
AND p2.lang =  'en'
AND t.trip_id =1
AND p.root_id =1
AND p.lft >39
AND p.rgt <44
ORDER BY p2.title

Это многоязычный сервис, поэтому у нас есть place_translation и category_translation. Мы получаем места, которые относятся к поездке и к городу (это вложенный набор, поэтому root_id, lft и rgt)

Индексы:

on table place: id, category_id
on table place_translation: id-lang index
on table trip_place: place_id, trip_id
on table category: id
on table category_translation: id-lang index

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

спасибо!

1 Ответ

2 голосов
/ 25 октября 2009

Есть две очевидные вещи. Поскольку у вас есть условия для значений из каждой таблицы в WHERE, требуется, чтобы вы нашли соответствующие строки в предложениях JOIN. Это означает, что вы должны использовать внутренние соединения, а не оставленные внешние соединения. Затем, чтобы отфильтровать результаты как можно скорее, вы можете переместить некоторые из условий с WHERE на JOIN .. ON.

Я также изменил порядок таблиц таким образом, который имеет смысл для меня, то есть сначала вы выбираете из trip_place, потому что вы знаете, что вам нужны только места из этой поездки. Затем для каждой строки из trip_place найдите соответствующий place, а для каждого place найдите соответствующий category. Переводы являются последними, потому что они не влияют на запрос функционально. Таким образом, запрос будет выглядеть примерно так:

SELECT
    p.id, p.image, p.lat, p.lng, 
    p.category_id, p2.title, p2.description, c2.name
FROM
    trip_place t
    JOIN place p ON p.id = t.place_id AND p.root_id = 1 AND p.lft > 39 AND p.rgt < 44
    JOIN category c ON p.category_id = c.id AND c.root_id = 1
    JOIN place_translation p2 ON p.id = p2.id AND p2.lang = 'en'
    JOIN category_translation c2 ON c.id = c2.id AND c2.lang = 'en'
WHERE
    t.trip_id = 1
ORDER BY p2.title

Я не могу сказать, действительно ли это быстрее, но это может быть. Вы должны запустить EXPLAIN на обоих из них. Из списка индексов, вероятно, следует добавить индекс на place (root_id, p.lft, p.rgt) (все они в виде одного индекса, а не каждого столбца в отдельности).

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