2016-05-10 2 views
1

У меня есть следующий запрос,Sub запроса на больших таблицах с присоединиться к крайне медленно

SELECT * FROM users, 
(SELECT * 
FROM mastery 
WHERE champion_rank = 1 
ORDER BY global_rank ASC 
LIMIT 3) as ranks 
WHERE users.id = ranks.user_id 

Мастерства имеет 22Й строки и пользователи имеют строки 5M. Для выполнения вышеуказанного запроса требуется 1800 мс.

Проблема заключается в том, что следующий подзапросе при запуске самого по себе занимает 2,5 мс для выполнения

SELECT * 
FROM mastery 
WHERE champion_rank = 1 
ORDER BY global_rank ASC 
LIMIT 3 

И для извлечения одного пользователя из таблицы пользователей занимает 2,5 мс

SELECT * FROM users WHERE id = 4234523 

Так теоретически, если я только что изменил свой код, чтобы сделать первый подзапрос, а затем для каждой возвращаемой строки выполните дополнительный запрос, для всего процесса потребуется 2,5 + (3 * 2,5) = 10 мс.

Неужели postgres делает что-то странное?

Структуру и индексы баз данных можно найти here

+2

Почему бы не использовать соединение? Кроме того, поставили ли вы индексы на стол? – JanR

+0

Пожалуйста, прочитайте http://stackoverflow.com/tags/postgresql-performance/info и http://wiki.postgresql.org/wiki/SlowQueryQuestions, затем измените свой вопрос и добавьте недостающую информацию. –

ответ

0

Вашего запроса выполняется медленно, так как он должен работать отсортированный подзапрос для каждого на строки 5Х в пользователях.

Вы бы гораздо лучше делать объединение один прохода, и использовать ранг() функцию окна для фильтрации 3 верхних те, которые вы хотите:

SELECT users.*, (ranks.mastery).* 
FROM (
    SELECT mastery, rank() OVER (ORDER BY global_rank) 
    FROM mastery 
    WHERE champion_rank = 1 
) as ranks 
JOIN users ON (users.id = ranks.user_id) 
WHERE ranks.rank <= 3; 
+0

Спасибо, что работает потрясающе, i решил это, изменив тип данных mastery.user_id и users.id на то же, но это немного более результативно. Не понимайте это на 100%, но попробуйте, когда я вернусь домой с работы – jromaior

0

Определена вопрос, тип данных для двух мест я присоединился к другим. Идентификатор пользователя Mastery был типом данных, а идентификатор Users был целым числом данных, он должен был отличать каждую строку к новому типу.

Следовательно, длительное время запроса.

+0

Что-то, что можно было бы увидеть в плане выполнения, если бы вы добавили это к своему вопросу. –

+0

Я определенно не эксперт по постгерам, я действительно взглянул на ANPLYIN ANALYZE запроса, но из этого не было интуитивно понятно, что это проблема, но я думаю, что это во многом связано с моей неопытостью с postgres – jromaior

+0

Что Я имел в виду: вы должны добавить план выполнения к своему первоначальному вопросу. Скорее всего, кто-то сразу заметил бы это. –

Смежные вопросы