2016-01-26 4 views
1

Я собираю некоторые данные (чирикать с хэштегом) и работать, чтобы создать статистику со следующей структурой таблицы:MySQL Оптимизация подзапросов & Order совокупным

enter image description here

Моя статистика целью является показать, как много детей и сколько впечатление на твит

Запрос:

SELECT parent.tweet_id, parent.tweet_text, parent.tweet_time, parent.tweet_image, parent.user_id, parent.user_name, parent.user_follower, parent.user_following, parent.is_retweet, parent.is_favorite, parent.is_reply, 
(
    SELECT COUNT(tweet_id) 
    FROM tweet 
    WHERE tweet_status = 1 && user_follower > 0 && is_retweet = parent.tweet_id 
) as child, 
(
    SELECT (COALESCE(SUM(user_follower),0) + parent.user_follower) 
    FROM tweet WHERE tweet_status = 1 && user_follower > 0 && is_retweet = parent.tweet_id 
) as impression 
FROM tweet AS parent 
WHERE parent.tweet_status = 1 AND parent.is_retweet = 0 AND parent.is_favorite = 0 AND parent.is_reply = 0 
ORDER BY parent.tweet_time DESC 

child: подсчитывать общее твиттере, is_retweet = скобка t.tweet_id

impression: parent.user_follower + сумма user_follewer где is_retweet = parent.tweet_id

Мой запрос слишком медленно при получении child и impression и я не знаю, как оптимизировать :(. Но, реальная проблема в том, когда я хочу найти 10 лучших ударных баз на показе, ORDER BY impression выглядят глупо.

Я ожидаю, что все это поможет упростить этот запрос :)

+0

Pls предоставляет список существующих индексов для всех затронутых таблиц, а также предоставляет результат объяснения вашего запроса. – Shadow

+0

Я бы начал с перемещения подзапросов из списка выбора в предложение from как производные таблицы. – Shadow

ответ

2

Я хотел бы начать с двигающимися подзапросами из списка выбора в ЕКЕ в производных таблиц. Вам нужен только один подзапрос, поскольку 2 подзапроса имеют одинаковое условие, включая критерий соединения. Полученная таблица должна быть сгруппирована с помощью is_retweet, потому что это представляет отношения родитель-потомок. Очевидно, что показы должны быть рассчитаны в списке выбора, так как производная таблица может предоставлять только последователей только для повторных твитов.

SELECT parent.tweet_id, parent.tweet_text, parent.tweet_time, parent.tweet_image, parent.user_id, parent.user_name, parent.user_follower, parent.user_following, parent.is_retweet, parent.is_favorite, parent.is_reply, 
COALESCE(t.child,0) as child, 
COALESCE(t.sum_child_follower,0) + parent.user_follower as impression 
FROM tweet AS parent 
LEFT JOIN 
(
    SELECT is_retweet, COUNT(tweet_id) as child, SUM(user_follower) as sum_child_follower 
    FROM tweet 
    WHERE tweet_status = 1 && user_follower > 0 
    GROUP BY is_retweet 
) as t ON t.is_retweet=parent.tweet_id 
WHERE parent.tweet_status = 1 AND parent.is_retweet = 0 AND parent.is_favorite = 0 AND parent.is_reply = 0 
ORDER BY parent.tweet_time DESC 

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

К сожалению, для получения только 10 лучших результатов вы должны использовать заказ по вычисленному полю показания и предел ограничения. Это не ускорит запрос, так как mysql должен рассчитать все показы, прежде чем он сможет сделать заказ.

+0

Большое вам спасибо, я использую ваш запрос, и у меня есть более высокая скорость :) Кстати, как использовать соответствующие индексы? Я использую ALTER TABLE 'tweet' ADD INDEX (' tweet_id'); –

+0

Несомненно, ваш дополнительный запрос должен вернуть столбец is_retweet, который используется для соединения? – Kickstart

+0

, так что правильный colomn для добавления индекса is_retweet? –

0

Это ваш запрос (по существу):

SELECT parent.*, 
     (SELECT COUNT(*) 
     FROM tweet t 
     WHERE t.tweet_status = 1 AND t.user_follower > 0 AND 
       t.is_retweet = parent.tweet_id 
     ) as child, 
     (SELECT (COALESCE(SUM(t.user_follower), 0) + parent.user_follower) 
     FROM tweet t 
     WHERE t.tweet_status = 1 AND t.user_follower > 0 AND 
       t.is_retweet = parent.tweet_id 
     ) as impression 
FROM tweet AS parent 
WHERE parent.tweet_status = 1 AND parent.is_retweet = 0 AND 
     parent.is_favorite = 0 AND parent.is_reply = 0 
ORDER BY parent.tweet_time DESC; 

Во многих ситуациях это, вероятно, лучший способ написать запрос. Вам нужны индексы: tweet(twee_status, is_retweet, is_vaforite, is_replay, tweet_time, tweet_id) и tweet(is_retweet, tweet_status, user_follower). Я думаю, что они удалят любую агрегацию или сортировку в таблице твитов, обрабатывая всю фильтрацию и вычисления в индексе.

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