Разница между вашими двумя решениями должна быть незначительной. Стол решение может быть чище в зависимости от активности.
Однако учтите, что «вы делаете это неправильно» (согласно теории).
Принцип разработки приложений СУБД четко гласит, что вы не должны пытаться указать, как должны выполняться ваши запросы, а какие данные вы хотите. База данных найдет оптимальный путь к вашему решению (СУБД находится ближе всего к данным и в зависимости от вашей архитектуры может сэкономить на обходах сети, обходах хранилища и т. Д.; Масштабируемость здесь может быть серьезно ограничена, и вы можете не знать об этом, если Вы не проводите приличное стресс-тестирование, кроме того, СУБД знает об индексах и внутренней статистике, которая определяет, будет ли сканирование или поиск более эффективным, и знает, как оптимально выполнять объединения).
На практике попробуйте поставить вопрос, почему разные базы для дружбы? (это действительно разные БД или разные схемы на одном БД?).
Кроме того, если вы действительно хотите пойти по этому пути (отключив СУБД для поиска оптимального плана выполнения), то наиболее важными факторами являются:
- индексы (повлияет на производительность на порядки)
- шаблоны использования (индексы улучшат производительность SELECT, но слишком большое количество индексов замедлит обновления)
- Кэширование на уровне приложения / клиента (может влиять на производительность и масштабируемость на порядки)
EDIT:
Итак, учитывая «Учитывая набор из N идентификаторов друзей, получите все открытые сессии или последнюю сессию для всех этих друзей». Вот запрос, который следует протестировать перед введением новых структур
Сеансов (SessionID, Пользователь, Контекст, Начало, Конец)
SELECT *
FROM Sessions s
WHERE s.End IS NULL
AND s.User IN (:friendsList)
UNION ALL
SELECT *
FROM Sessions s
WHERE s.User NOT IN (SELECT User
FROM Sessions s2
WHERE s2.User IN (:friendsList)
AND s2.End IS NULL)
AND s.User IN (:friendsList)
AND s.End IN (SELECT MAX(End)
FROM Sessions s2
WHERE s2.User = s.User)
Есть и другие способы написания вышеприведенного, чтобы попытаться помочь оптимизатору, в частности, если ваша БД поддерживает CTE, вышеприведенное можно переписать более эффективно.
Примечания:
:friendsList
- список пользователей, которые являются друзьями.
Кроме того, я предполагаю, что для открытых сессий значение NULL равно End
для открытых сессий. Возможно, вы уже выбрали какой-то другой подход (возможно, у вас есть поле, обозначающее его; или есть две таблицы, одна для открытых сессий, одна для закрытых)
Вышеупомянутый запрос получит выгоду от определенных индексов (принцип состоит в том, чтобы сначала попытаться оптимизировать с помощью индексов, затем с реструктуризацией; первый индекс, который я бы попробовал, это составной индекс на User, End
) и относительно небольшое количество друзей (предполагается из факт, что это передается как строка), это должно уже работать прилично.