2013-12-22 3 views
1

У меня есть таблица симпозиумов/антипатий, которая содержит около 5 миллионов строк. Когда я использую следующий запрос для получения данных, он заканчивается через 2 + минуты. Есть ли лучший подход к тому, как я храню и получаю симпатии/антипатии? Каждый раз, когда кому-то нравится/не нравится сообщение, он добавляет столбец в db. 0 За неприязнь и 1 за подобное. Затем мне нужна сумма обоих столбцов для каждого пользователя, а затем возвращать пользователям наибольшее количество понравившихся против антипатии. Если я выберу SUM для симпатий/антипатий, запрос вернется через 4 секунды. У меня также есть индексы на UserID и все, что я группирую. Вот запрос:Очень медленная производительность на SUM SQL Server 2008

SELECT TOP 50 
    Flows_Users.UserName, 
    Flows_Users.UserID,Flows_Users.ImageName, 
    Flows_Users.DisplayName,   
    Flows_UserBios.bio, 
    FlowsCount = (SELECT Count(1) FROM Flows_Flows 
        WHERE UserID = Flows_Users.UserID AND Flows_Flows.Active = '1'), 
    BeatsCount = (SELECT Count(1) FROM Flows_Beats 
        WHERE UserName_ID = Flows_Users.UserID AND Flows_Beats.Active = '1'), 
    FollowersCount = (SELECT Count(1) FROM Flows_Follow 
         WHERE FOLLOWING = Flows_Users.UserID), 
    FollowingCount = (SELECT Count(1) FROM Flows_Follow 
         WHERE FOLLOWER = Flows_Users.UserID), 
    ISNULL(SUM(Flows_Flows_Likes_Dislikes.[Like]) , 0) AS Likes, 
    ISNULL(SUM(Flows_Flows_Likes_Dislikes.Dislike), 0) AS DisLikes 
FROM 
    Flows_Users 
INNER JOIN 
    Flows_Flows ON Flows_Users.UserID = Flows_Flows.UserID 
INNER JOIN 
    Flows_UserBios ON Flows_Users.UserID = Flows_UserBios.userid 
INNER JOIN 
    Flows_Flows_Likes_Dislikes ON Flows_Flows.FlowID = Flows_Flows_Likes_Dislikes.FlowID 
WHERE 
    Flows_Users.UserID = Flows_Users.UserID 
GROUP BY 
    Flows_Users.UserID, 
    Flows_Users.UserName, 
    Flows_Users.ImagePath,  
    Flows_Users.ImageName, 
    Flows_Users.DisplayName, 
    Flows_UserBios.bio 
ORDER BY 
    [Likes] DESC, [Dislikes] ASC, FlowsCount DESC 
+1

Вам понадобится серьезно отформатировать запрос так долго. –

+2

Вы посмотрели план выполнения? – Blorgbeard

+0

@Blorgbeard Я запустил его, и проблема в том, что два типа S/S не нравятся. Когда я удаляю эту часть, запрос почти мгновен. – nawlrus

ответ

3

Не рекомендуется присоединяться к таблице из 5 миллионов строк. Если вы посмотрите на план выполнения, я уверен, вы обнаружите, что соединение между потоками и Likes_Dislikes - hashjoin - это худший возможный случай.

Первым шагом в оптимизации этого запроса является определение того, какое конкретное соединение добавляет время на выполнение. Предположительно, есть часть этого запроса, которая выполняется в приемлемое время (например, 1-2 секунды). Все остальное - проблема. И проблемы решаются путем денормализации таблиц. Вместо того, чтобы присоединяться к таблице «любит/не нравится», добавьте столбец «любит/не нравится» в «Таблица потоков». Всякий раз, когда вы вставляете предпочтения/антипатии, немедленно обновляйте запись потока. Делая это, вам не понадобится тяжелое соединение в этом запросе.

Имейте в виду, что нормализация является четко определенной теорией, но эта практика часто идет вразрез с ней. Устранение правильного баланса между нормализованными таблицами и избыточность делает отличное программное обеспечение.

+0

Я соглашаюсь на денормализацию этого в отношении таких значений. И это может ЛЕГКО обрабатываться с помощью простых триггеров. – DRapp

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