SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 27.03.2012 12:13:19

jumanji
Участник
Зарегистрирован: 27.03.2012
Сообщений: 6

сортировка результатов вложенного запроса

Доброго времени суток.

Вот несколько сокращенная структура моего запроса:


SELECT ..., (SELECT ...
            FROM ...
            WHERE ...) as sort_field
FROM table
WHERE table_field = 1
ORDER BY sort_field DESC
 

Без сортировки запрос выполняется ~3 сек, а с сортировкой - все 6. И это не смотря на то, что на выходе получается всего-то каких-то жалких 6 строк, которые нужно отсортировать.
Получается, что mysql сортирует какие-то промежуточные результаты вместо того, чтобы отсортировать конечные 6 строк.
Вот как добиться обратного?

Спасибо.

Неактивен

 

#2 27.03.2012 12:21:44

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: сортировка результатов вложенного запроса

Что дает EXPLAIN запроса с сортировкой и без?

Неактивен

 

#3 27.03.2012 13:26:28

jumanji
Участник
Зарегистрирован: 27.03.2012
Сообщений: 6

Re: сортировка результатов вложенного запроса

с сортировкой

1    PRIMARY    user    ALL                    57343    Using where; Using filesort
2    DEPENDENT SUBQUERY    match_result    ALL                    173080    Using where
2    DEPENDENT SUBQUERY    initiator_user    ref    vk_id    vk_id    5    Pinball.match_result.initiator_vk_id    1    
2    DEPENDENT SUBQUERY    competitor_user    ref    vk_id    vk_id    5    Pinball.match_result.competitor_vk_id    1    Using where


без
1    PRIMARY    user    ALL                    57343    Using where
2    DEPENDENT SUBQUERY    match_result    ALL                    173081    Using where
2    DEPENDENT SUBQUERY    initiator_user    ref    vk_id    vk_id    5    Pinball.match_result.initiator_vk_id    1    
2    DEPENDENT SUBQUERY    competitor_user    ref    vk_id    vk_id    5    Pinball.match_result.competitor_vk_id    1    Using where


вот как выглядит весь запрос:
SELECT vk_id as u_vk_id, ( SELECT
                sum(if(initiator_vk_id = u_vk_id, initiator_earned_general_points, competitor_earned_general_points))
            FROM match_result LEFT JOIN `user` as initiator_user ON initiator_vk_id = initiator_user.vk_id
                                                                    AND initiator_user.special_champ = 1
                LEFT JOIN `user` as competitor_user ON competitor_vk_id = competitor_user.vk_id
                                                        AND competitor_user.special_champ = 1
            WHERE type = 1
                    AND (initiator_vk_id = u_vk_id
                    OR competitor_vk_id= u_vk_id )) as earned_points
FROM `user`
WHERE special_champ = 1
ORDER BY earned_points DESC

Отредактированно jumanji (27.03.2012 13:31:56)

Неактивен

 

#4 27.03.2012 13:37:59

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: сортировка результатов вложенного запроса

Попробуйте добавить индекс на special_champ.

ALTER TABLE `user` ADD KEY(`special_champ`);

или составной KEY(`special_champ`, `earned_points`);

Неактивен

 

#5 27.03.2012 14:05:06

jumanji
Участник
Зарегистрирован: 27.03.2012
Сообщений: 6

Re: сортировка результатов вложенного запроса

добавление индекса на special_champ не помогло.

Поясните, пожалуйста, про составной KEY

Неактивен

 

#6 27.03.2012 14:14:07

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: сортировка результатов вложенного запроса

Про составные индексы см. http://sqlinfo.ru/forum/viewtopic.php?id=151

Учитывая, что у Вас всего 6 строчек во внешней таблице, это вряд ли основная проблема. А что если выполнить 6 раз вложенный запрос? Еще попробуйте переписать весь запрос через JOIN, вместо подзапроса.

Неактивен

 

#7 27.03.2012 14:38:08

jumanji
Участник
Зарегистрирован: 27.03.2012
Сообщений: 6

Re: сортировка результатов вложенного запроса

Нет, во внешней таблице у меня не 6 строк. Я имел ввиду то, что результатом вот этого запроса

SELECT vk_id as u_vk_id, ( SELECT
                sum(if(initiator_vk_id = u_vk_id, initiator_earned_general_points, competitor_earned_general_points))
            FROM match_result LEFT JOIN `user` as initiator_user ON initiator_vk_id = initiator_user.vk_id
                                                                    AND initiator_user.special_champ = 1
                LEFT JOIN `user` as competitor_user ON competitor_vk_id = competitor_user.vk_id
                                                        AND competitor_user.special_champ = 1
            WHERE type = 1
                    AND (initiator_vk_id = u_vk_id
                    OR competitor_vk_id= u_vk_id )) as earned_points
FROM `user`
WHERE special_champ = 1

является массив из 6 строк (по 2 значения).

И вот этот-то массив мне и нужно отсортировать по созданному мной полю earned_points. Ну, казалось бы, плёвое дело. Ан нет.

Неактивен

 

#8 27.03.2012 14:44:16

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: сортировка результатов вложенного запроса

Я имел в виду, что 6 строк с условием special_champ=1. Значит можно просто выполнить внутренний запрос 6 раз - как 6 отдельных запросов.

Неактивен

 

#9 27.03.2012 15:00:00

jumanji
Участник
Зарегистрирован: 27.03.2012
Сообщений: 6

Re: сортировка результатов вложенного запроса

А, ясно.
Ну да, именно к этому я и начал склоняться. Вы имеете ввиду, разбить сложный запрос на два запроса и внутренний запрос сформировывать с помощью php?
Кстати, внутренний запрос выполняется всего за 0.094 секунды.

Неактивен

 

#10 27.03.2012 15:06:48

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: сортировка результатов вложенного запроса

Да, внутренний можно выполнять в цикле из PHP. Скорее всего вы стали жертвой неоптимальности работы подзапросов в MySQL. Альтернатива - переписать весь запрос через JOIN вместо подзапроса.

Неактивен

 

#11 27.03.2012 19:00:55

jumanji
Участник
Зарегистрирован: 27.03.2012
Сообщений: 6

Re: сортировка результатов вложенного запроса

В итоге реализовал в виде двух запросов.

Спасибо за помощь.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson