Как я могу улучшить производительность моего подзапроса? - PullRequest
0 голосов
/ 10 августа 2011

У меня проблемы с производительностью запросов IN в MYSQL.

В основном я строю график друзей, и когда пользователь ~ <5 друзей, он медленно сканирует </p>

однако для пользователей с большими друзьями (7000+) - он работает супер быстрее.

Вот мой макет-запрос:

SELECT *
FROM activity
WHERE user_id IN 
(
   SELECT friend_id
   FROM friends
   WHERE user_id = 1 and approved = 1
)
order by activity.created_at DESC
LIMIT 25

По какой-то причине, если у user_id <5 друзей, запросу требуется 15 секунд, чтобы вернуть 0 записей. </p>

В таблице друзей у меня есть индекс user_id, и он утвержден. В записи активности у меня есть индекс на creat_at.

Любые предложения или ре-факторинг?

Ответы [ 4 ]

1 голос
/ 10 августа 2011

Как правило, подзапрос в вашем примере будет выполняться для каждой строки, выбранной из таблицы activity, вы можете уменьшить ее, переместив фильтр таблицы activity во внешнюю область видимости, поэтому постарайтесь, чтобы ваш запрос верхнего уровня был более конкретно с точки зрения фильтрации.

Попробуйте INNER JOIN, работает ли он быстрее?

SELECT * FROM activity a
INNER JOIN friends f ON a.user_id = f.friend_id
WHERE a.user_id = 1 AND f.approved = 1
order by activity.created_at DESC LIMIT 25 

Несколько вопросов:

  • В обеих таблицах есть столбец user_id?
  • одобренный столбец в таблице друзей?
0 голосов
/ 10 августа 2011
SELECT a.* FROM activity a, friends f
WHERE 
           a.user_id = f.friend_id
    AND    f.user_id = 1 
    AND    f.approved = 1
ORDER BY activity.created_at DESC 
LIMIT 25

Иметь индекс для каждого: a.user_id, f.friend_id и f.user_id.

НЕ индексировать f.approved, поскольку это очень вероятный столбец с низкой кардинальностью.

0 голосов
/ 10 августа 2011
Select * 
FROM activity a
JOIN (Select * from friends WHERE user_id = 1 and approved = 1) f
ON a.user_id = f.friend_id
ORDER BY a.created_at DESC
LIMIT 25

По сути, IN являются непредсказуемыми, я люблю использовать JOIN, когда это возможно.

0 голосов
/ 10 августа 2011

Будет ли это

SELECT * FROM activity t1 join friends t2 where t1.user_id=t2.friends_id and t2.user_id=1 and t2.approved=1 order by activity.created_at DESC LIMIT 25

сделать то же самое. И это быстрее?

Я думаю, вам понадобится индекс для friend_id, user_id, одобренный для таблицы друзей.

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