

Проверьте эту статью:
Визуальное объяснение SQL-соединений
Внутреннее соединение:

Левое внешнее соединение:

Правое внешнее соединение:

Обязательно прочтите все комментарии в статье, потому что представление объединений в виде операций над множествами вызывает резкую критику! Например, левое соединение НЕ является пересечением, поскольку оно создает новые кортежи.
Диаграмма была бы лучше, если бы она также показывала ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ. Поскольку разные виды объединений дают разные результаты, вопрос о производительности в некоторой степени не имеет значения. Вам следует выбрать тот, который дает требуемый результат. Производительность зависит от внутренней части СУБД.
ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ - это всего лишь полнота обоих кругов, так что действительно ли это нужно в диаграмме?
Надеюсь, вы понимаете картинки. По производительности они равноценны - без разницы.
Обновлено: Ой. Думаю, вас не волновала эта часть ответа.
LEFT JOIN B такой же, как B RIGHT JOIN A. В некоторых СУБД нет RIGHT JOIN, поэтому вам придется переписать логику RIGHT JOIN на логику LEFT JOIN.
A 1 2 3
B 2 3 4 3
SELECT A.I FROM INNER JOIN B ON B.I = A.I;
output: 2 3, 3
SELECT A.I AS X, B.I AS Y FROM A LEFT JOIN B ON B.I = A.I;
read above code as A on LEFT, JOINs B
output:
X Y
1 NULL
2 2
3 3
3 3
SELECT A.I AS X, B.I AS Y FROM B RIGHT JOIN A ON A.I = B.I;
Прочтите приведенный выше код как B on RIGHT, JOINs A. Это то же самое, что А слева
Все, что находится слева, всегда оценивается, всегда выводится. Вы можете представить A LEFT JOIN B, B RIGHT JOIN A как:
var result = new Dictionary<int, int?>();
var A = new int[] { 1, 2, 3 };
var B = new int[] { 2, 3, 4, 3 };
foreach (int aElem in A)
{
bool hasMatch = false;
foreach (int bElem in B)
{
if (bElem == aElem)
{
result.Add(aElem, bElem);
hasMatch = true;
}
}
if (!hasMatch)
result.Add(aElem, null);
}
foreach(int X in result.Keys)
{
MessageBox.Show(string.Format("X {0} Y {1}", X, result[X].HasValue ? result[X].Value.ToString() : "NULL" ));
}
Сравнение производительности между типами объединений не имеет значения, поскольку они дают разные наборы результатов. Даже если внутреннее соединение выполняется быстрее, вы не стали бы его использовать, если бы вам потребовались результаты левого соединения (которое включает даже записи, которые не соответствуют второй таблице в соединении).
Левый, правый, внутренний и внешний не влияют на производительность, и они уже здесь хорошо объяснены.
Однако есть подсказки, которые вы можете добавить к соединениям, которые влияют на производительность: хэш, цикл и слияние.
Обычно планировщик запросов решает, что из этого делать, но иногда вы можете улучшить производительность, переопределив это.
loopjoin просматривает каждую строку второй таблицы для каждой строки первой. Это хорошо, если у вас есть один очень большой стол, а другой намного меньше.
mergejoin просматривает обе таблицы вместе по порядку. Это может быть очень быстро, если обе таблицы уже упорядочены по полю, к которому вы присоединяетесь.
hashjoin использует множество временных таблиц для группировки вывода при сортировке объединенных данных.
Некоторые специализированные БД также поддерживают другие типы, такие как соединения растровых изображений.
Часть 2 вопроса касалась производительности, которая не обязательно напрямую связана с методом соединения. Были ли у вас какие-либо дополнительные комментарии по этому поводу?