Помогите мне оптимизировать этот запрос - PullRequest
0 голосов
/ 26 сентября 2011

У меня есть этот запрос для приложения, которое я разрабатываю.Есть таблица ссылок, таблица авторов и таблица reference_authors.Существует подзапрос, чтобы вернуть всех авторов для данной ссылки, которые я затем отображаю в формате php.Подзапрос и запрос, выполняемые по отдельности, хороши и быстры.Однако, как только подзапрос помещен в основной запрос, выполнение всего занимает более 120 секунд.Я был бы признателен за свежие взгляды на это.Спасибо.

SELECT
rf.reference_id,
rf.reference_type_id,
rf.article_title,
rf.publication,
rf.annotation,
rf.publication_year,
(SELECT GROUP_CONCAT(a.author_name)
FROM authors_final AS a
INNER JOIN reference_authors AS ra2 ON ra2.author_id = a.author_id
WHERE ra2.reference_id = rf.reference_id
GROUP BY ra2.reference_id) AS authors
FROM
references_final AS rf
INNER JOIN reference_authors AS ra ON rf.reference_id = ra.reference_id
LEFT JOIN reference_institutes AS ri ON rf.reference_id = ri.reference_id;

Вот фиксированный запрос.Спасибо ребята за рекомендации.

SELECT
rf.reference_id,
rf.reference_type_id,
rf.article_title,
rf.publication,
rf.annotation,
rf.publication_year,
GROUP_CONCAT(a.author_name) AS authors
FROM
references_final as rf
INNER JOIN (reference_authors AS ra INNER JOIN authors_final AS a ON ra.author_id = a.author_id)
ON rf.reference_id = ra.reference_id
LEFT JOIN reference_institutes AS ri ON rf.reference_id = ri.reference_id
GROUP BY rf.reference_id

Ответы [ 2 ]

0 голосов
/ 26 сентября 2011

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

От 120 секунд до 78 миллисекунд это неплохое улучшение - примерно на три порядка. Возьмите остаток выходного дня.

Когда вы вернетесь завтра, начните искать другие подзапросы в вашем исходном коде.

0 голосов
/ 26 сентября 2011

Вы говорите, что подзапрос хорош и быстр в изоляции, но теперь он, очевидно, работает для каждой отдельной строки - 100 строк = 100 подзапросов.

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

Один из вариантов - оставить авторам объединения и создать декартово произведение - вам будет возвращено намного больше строк, и вам потребуется некоторый код, чтобы получить тот же конечный результат, но это уменьшит нагрузку на БД и будет работать быстрее .

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

...