Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 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