Как я могу оптимизировать этот SQL-запрос с помощью вложенных SELECT? - PullRequest
0 голосов
/ 26 декабря 2011

У меня следующий запрос:

SELECT src_big, created, modified, owner, aid, caption 
FROM photo 
WHERE aid IN (SELECT aid, modified FROM album WHERE owner IN (SELECT uid2 FROM friend WHERE uid1=me() or uid2 = me())order by modified desc) 
ORDER BY created DESC 
LIMIT 30

Это работает довольно медленно, и я уверен, что из-за вложенного SELECT и т. Д. Как я могу сделать это быстрее? Как это должно быть переписано для лучшей оптимизации?

Ответы [ 3 ]

1 голос
/ 26 декабря 2011

попробуйте использовать соединения вместо SubQuery, это быстрее:

SELECT photo.src_big, photo.created, photo.modified, photo.owner, photo.aid, 
photo.caption FROM photo 
inner join album on album.aid = photo.aid 
inner join  friend on album.owner = friend.uid2 
WHERE uid1=me() or uid2 = me()
order by modified desc,created DESC LIMIT 30

Примечание: вам нужно поставить имена таблиц в конце

1 голос
/ 26 декабря 2011

У нас есть несколько случаев в наших играх на Facebook, где такая функциональность необходима, и у нас было много проблем с ней.В mySQL кажется, что каждая строка внешнего запроса будет перезапускать вложенный запрос, который будет перезапускать вложенный запрос, что делает его очень медленным.Мы обнаружили, что возвращать результаты внутреннего запроса в php, объединять его и затем запускать следующий запрос со скомпилированным списком было очень быстро.Не уверен, что есть решение, полностью находящееся внутри mySQL, но это решение у нас работает достаточно хорошо.

Другая потенциальная проблема может заключаться в индексации, вам нужно убедиться, что все столбцы, по которым вы ищите или упорядочиваетепо правильно проиндексированы.Использование функции MySQLs Explain в вашем запросе также поможет найти проблемы.

0 голосов
/ 26 декабря 2011

Вы можете сделать это объединением

select (stuff) from photo join album
on photo.aid = album.aid join friend
on album.owner = friend.uid2 
where friend.uid1 = me() or friend.uid2 = me()
order by created desc limit 30

НО учтите: поскольку вы используете хранимые функции, это никогда не попадет в кеш запросов.

Вы можете увидеть, что происходит с вашим запросом, предварительно обратив его с помощью «desc» - это покажет вам, как оптимизатор работает с ним.

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