![]() |
Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
2 таблицы: пользователи (friends) и друзья (users)
Структура таблицы друзей:
CREATE TABLE IF NOT EXISTS `friends` (
`user1` int(10) unsigned NOT NULL default '0',
`user2` int(10) unsigned NOT NULL default '0',
`status` enum('pending','active') NOT NULL default 'pending',
`from` int(11) NOT NULL default '0',
`date` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`user1`,`user2`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;В таблицу пользователи заносятся так: в user1 - минимальный id среди друзей, в user2 - максимальный
user1 = min($user1, $user2), user2 = max($user1, $user2)
Дабы исключить повторений
делаю выборку всех пользователей с проверкой является ли данный пользователь другом:
SELECT
u.*,
EXISTS( SELECT *
FROM friends
WHERE
( user1 = $my_id
AND user2 = u.id
) OR (
user1 = u.id
AND user2 = $my_id
)
AND `status` = 'active'
) AS friend
FROM
users AS u
ORDER BY usernameИз-за:
( user1 = $my_id
AND user2 = u.id
) OR (
user1 = u.id
AND user2 = $my_id
)Запрос работает не оправданно долго. Индекс в под запросе не используется...
Без дополнительного OR:
WHERE
user1 = $my_id
AND user2 = u.id
AND `status` = 'active'включается индекс и запрос выполняется быстро. Но в таком виде не известно какой параметр меньше $my_id или u.id что бы правильно присвоить их полям user1 и user2
Подскажите как мне оптимизировать запрос либо структуру таблицы друзей...
Отредактированно maxtor (21.07.2010 13:09:39)
Неактивен

Есть несколько мыслей.
1. А почему у Вас дружба только обоюдная? ![]()
2. Если у Вас такие странные правила подружения, то почему бы
не воспользоваться знанием id1 < id2 и не делать два простых
запроса, которые у Вас работают, на соответствующих поддиапа-
зонах id?
3. Зачем нужен exists, когда достаточно сделать LEFT JOIN?
Неактивен
paulus, ну почему странные? Как во всех социалках: отправляешь запрос на дружбу, если второй подтверждает, то он появляется в твоем списке друзей, а ты в его.
На счет id1 < id2 не совсем понял, как это можно применить. Можете показать это в запросе?
Неактивен
Понял, что вы имели введу:
user1 = IF ($my_id < u.id, 1, u.id) AND user2 = IF($my_id > u.id, 1, u.id) AND `status` = 'active'
Да, индексы подключились, запрос выполняется быстро. Спасибо
Неактивен

Странно, что тут работает
Я имел в виду SELECT … UNION SELECT ….
Неактивен
Страниц: 1