Сравнение запросов SQL JOIN

Следующее объяснение взято из книги: Графические базы данных. Робинсоном, Яном, Джимом Уэббером и Эмилем Эйфремом. в "O'Reilly Media, Inc.", 2013 г.


Скажем, есть 2 таблицы:

Человек

ID, Person
1, Alice  
2, Bob  
..,..  
99, Zach 

ЧеловекДруг

ID, Person 
1, 2   
2, 1  
2, 99  
..,..  
99,1

Пример 2-1. Друзья Боба

SELECT p1.Person 
FROM Person p1 
    JOIN PersonFriend   
        ON PersonFriend.FriendID = p1.ID  
    JOIN Person p2  
        ON PersonFriend.PersonID = p2.ID  
WHERE p2.Person = 'Bob'    

Основываясь на данных нашей выборки, ответ - Алиса и Зак. Это не особенно затратный или сложный запрос, поскольку он ограничивает количество рассматриваемых строк с помощью фильтра WHERE Person.person = 'Bob'.

Дружба не всегда рефлексивная, поэтому в примере 2-2 мы задаем ответный вопрос: «Кто дружит с Бобом?

Пример 2-2. Кто дружит с Бобом?

SELECT p1.Person 
FROM Person p1 
     JOIN PersonFriend  
        ON PersonFriend.PersonID = p1.ID 
     JOIN Person p2
        ON PersonFriend.FriendID = p2.ID 
WHERE p2.Person = 'Bob'

Ответ на этот вопрос - Алиса; к сожалению, Зак не считает Боба другом. Этот взаимный запрос по-прежнему легко реализовать, но на стороне базы данных он дороже, потому что теперь база данных должна учитывать все строки в таблице PersonFriend. Мы можем добавить индекс, но это по-прежнему связано с дорогостоящим косвенным обращением.


Все вышесказанное взято из книги и не является моим мнением. Что я не понимаю 1) почему запрос в примере 2-2 дороже, чем запрос в примере 2-1?
2) почему это называется ответным запросом?

Почему вы думаете, что один запрос будет работать хуже, чем другой? Вы проверили планы выполнения обоих? В частности, если у вас настроены соответствующие индексы для двух таблиц, любой запрос, вероятно, может выполняться быстро.

Tim Biegeleisen 03.12.2018 15:53
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
1
84
1

Ответы 1

  1. Единственное, что, как я вижу, может повлиять на производительность, - это то, как определяются индексы. Дело 1: ваш единственный индекс находится на (PersonID, FriendID). Все известные мне БД будут создавать индекс B-дерева по умолчанию и смогут использовать его для поиска только на PersonID. Следствие: деталь ON PersonFriend.PersonID = p2.ID WHERE p2.Person = 'Bob', вероятно, будет ее использовать и будет быстрой. Для второго запроса этого не будет. Случай 2: У вас есть 2 отдельных индекса, по одному на каждый столбец (PersonID) и (FriendID). В этой ситуации 2 запроса будут эквивалентны с точки зрения производительности (они будут просто использовать каждый из индексов).

  2. Не принимайте ответный запрос как технический термин, потому что это не то, что есть. Автор просто перевернул JOIN. В первом запросе первым появляется FriendID, а вторым - PersonID. Это дает ответ: кому нравится Боб?
    Напротив, второй запрос делает сначала соединения с PersonID, а вторыми - с FriendID. Это дает ответ на вопрос: кому нравится Боб? (то есть: дружба была взаимный)

Другие вопросы по теме