2012-03-22 2 views
0

Когда я делаю запросы в своей базе данных - у меня возникают проблемы с масштабированием, если у пользователя есть друзья 10k - тот же запрос, который я использую для пользователей с друзьями 2k, не масштабируется что означает, что для обработки требуется очень много времени.Сканирование запросов MySQL (Straight_Join vs Inner Join)

Типичная ситуация заключается в том, что, когда счетчик друзей пользователя достигает определенного порога, мне нужно в конечном итоге использовать STRAIGHT_JOIN, чтобы вытащить запрос, однако мне нужно написать условный оператор, чтобы сначала увидеть, сколько друзей и затем перейти оттуда , Чем больше данных, тем медленнее получается запрос.

Есть ли лучший способ увеличить ваши запросы через MySQL, чтобы они работали с одинаковой скоростью независимо от того, сколько данных генерируется или я живу в мире фантазий?

EDIT: Запрос перечислены ниже:

SELECT photos.photo_id, count(distinct photo_views.ip_address) as total_count 
FROM photos 
INNER JOIN friends on friends.friend_id = photos.user_id 
INNER JOIN photo_views on photos.photo_id = photo_views.photo_id 
WHERE friends.user_id = 1 and friends.approved = 1 
and photos.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY) 
GROUP by photos.photo_id 
ORDER by total_count desc 

Индексы фотографии являются:

[user_id, created_at, photo_id], [user_id], [photo_id] - PRIMARY 

Индексы друзей являются:

[user_id, approved], [friend_id], [user_id, friend_id] - PRIMARY 

Индекс по photo_views являются:

[photo_id] - PRIMARY 
+0

STRAIGHT_JOIN просто помогает, когда вы ЗНАЕТ правильное отношение таблиц и не хотите, чтобы двигатель думать за вас. Если вы можете опубликовать запрос, который вы пытаетесь запустить, могут быть другие параметры, такие как лучшие индексы, или когда/где корректировать предложения WHERE и т. Д. – DRapp

+0

Я просто добавил запрос выше. – gregavola

ответ

1

Я бы начал с ваших друзей FIRST в качестве вашего квалификатора, чтобы он не пытался смотреть на Фотографии в качестве основы, которая охватывала бы всех ... Поскольку вы делаете (Внутреннее) соединение, я бы пошел с straight_join таких как:

SELECT STRAIGHT_JOIN 
     P.Photo_ID, COUNT(distinct PV.IP_Address) as Total_Count 
    FROM 
     Friends F 
     JOIN Photos P 
      ON F.Friend_ID = P.User_ID 
      AND P.Created_At >= date_Sub(now(), Interval 30 day) 
      JOIN Photo_Views PV 
       ON P.Photo_ID = PV.Photo_ID 
    WHERE 
      F.User_ID = 1 
     AND F.Approved = 1 
    GROUP BY 
     P.Photo_ID 
    ORDER BY 
     total_Count DESC 

Таким образом, вы начинаете ТОЛЬКО с этими друзьями для одного пользователя, который одобрен. Из этого, присоединяйтесь к фотографиям друзей И дата будет квалифицирована ... из этого, получите, сколько хитов в таблице представлений

+0

Это выглядит действительно хорошо и начинает опрокидываться в тестах запросов. Пользователи с низким и средним значением - скрипт работает отлично. Однако - как только вы начинаете получать в друзья 15k, запрос занимает около 5 секунд для обработки. Есть идеи? – gregavola

+0

@gregavola, добавьте указатель на свои фото_оценки (photo_id, ip_address). Это, вероятно, убивает ваш счет ... – DRapp

+0

Я пробовал это, и для пользователей с друзьями 15k + все еще требуется около 4-5 секунд. Он использует все правильные индексы (user_id, is_approved) друзей, (user_id) - фотографии, (user_id, ip_address) на photo_views. Очень странно ... – gregavola