Привет, stackoverflow (мой первый вопрос!),
Мы делаем что-то вроде SNS, и у нас возник вопрос об оптимизации запросов.
Используя mysql 5.1, текущая таблица была создана с помощью:
CREATE TABLE friends(
user_id BIGINT NOT NULL,
friend_id BIGINT NOT NULL,
PRIMARY KEY (user_id, friend_id)
) ENGINE INNODB;
Демонстрационные данные заполняются следующим образом:
INSERT INTO friends VALUES
(1,2),
(1,3),
(1,4),
(1,5),
(2,1),
(2,3),
(2,4),
(3,1),
(3,2),
(4,1),
(4,2),
(5,1),
(5,6),
(6,5),
(7,8),
(8,7);
Бизнес-логика: нам нужно выяснить, какие пользователи являются друзьями или друзьями друзей для данного пользователя. Текущий запрос для пользователя с user_id=1:
SELECT friend_id FROM friends WHERE user_id = 1
UNION
SELECT DISTINCT friend_id FROM friends WHERE user_id IN (
SELECT friend_id FROM friends WHERE user_id = 1
);
Ожидаемый результат (порядок не имеет значения):
2
3
4
5
1
6
Как видите, приведенный выше запрос дважды выполняет подзапрос «ВЫБЕРИТЕ ИД_друга ИЗ друзей, ГДЕ ИД_пользователя = 1».
Итак, вот вопрос. Если вас больше всего беспокоит производительность, как бы вы изменили приведенный выше запрос или схему?
Заранее спасибо.
(1, 2)
. Нужна ли вашей таблице соответствующая строка(2, 1)
? И возможен ли сценарий, в котором 1 дружит с 2, но 2 не дружит с 1. Например, ваш список контактов MSN, где вы можете иметь[email protected]
в своем списке, но он не обязательно имеет вас в своем списке. - person Salman A   schedule 22.01.2011UNION ALL
, либо не используйте DISTINCT. Наличие двух шагов для удаления дубликатов не ускорит процесс. - person a_horse_with_no_name   schedule 22.01.2011