2016-01-31 2 views
0

У меня есть SQL запрос следующим образом:Оптимизация производительности рант с внутренним соединением

SELECT `users`.`name`, `users`.`username`, `users`.`bio`, `users`.`city`, `users`.`photo` 
FROM (`onlines`) JOIN `users` 
ON `onlines`.`username`=`users`.`username` 
WHERE `users`.`offline_status` = 0 
AND `users`.`perma_ban` = 0 
AND `users`.`is_premium` = 1 
GROUP BY `onlines`.`username` 
ORDER BY RAND() LIMIT 27 

Я использую RAND, но я не доволен производительностью. Как я могу оптимизировать этот запрос?

Я прочитал это:

How can i optimize MySQL's ORDER BY RAND() function?

Но я использую внутреннее соединение, так что этот вопрос не помог мне.

ответ

0

Первый выбрать 27 случайных usernames случайным образом из users, учитывая это ограничение:

WHERE `users`.`offline_status` = 0 
    AND `users`.`perma_ban` = 0 
    AND `users`.`is_premium` = 1 

Тогда вы почти до конца. onlines предоставляет почти ничего для запроса; все, что он делает, это исключить любые имена пользователей, которые не отображаются в onlines. Так просто добавить

AND NOT EXISTS (SELECT * FROM onlines WHERE username = users.username) 

Затем уходят в ссылку, указанную или my blog, который масштабируется лучше. Он обеспечивает 5 эффективных ответов. Но, не отвечая на несколько вопросов, я не могу сказать, какой из ответов лучше всего подходит вашей ситуации.

+0

У меня 350K записей в таблице пользователей и приблизительно 1k в таблице onlines. Получение 27 случайных имен пользователей из таблицы пользователей имеет смысл? Что Вы думаете об этом? –

+0

Это становится беспорядочным - вам либо нужно получить 27 из 1K плюс проверить 3 флажка, либо получить 27 из 350K плюс проверить, что они в сети. В любом случае вам, возможно, придется искать намного больше, чем 27, прежде чем критерии будут выполнены. Соответствует ли «offline_status» существованию в 'onlines'? Это может упростить запрос _a lot_. –

+0

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

0

Один из способов заключается в том, чтобы добавить пункт where. Итак, если вы знаете примерно, сколько строк будет соответствовать условиям, вы можете уменьшить данные. Итак, если вы знаете, что около 1000 сделать, то случайно занимает около 50 из них до окончательного order by:

and rand()*1000 < 50 

Конечно, вам нужны оценки общего количества.

+0

http://prntscr.com/9xfalx Я пробовал, как это, но это вернуло только строку. –

+0

Это условие содержится в разделе 'where' в разделе' group by'. –

+0

Нужно ли удалять "order by rand()"? –

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