FULL JOIN и MySQL |
||
Полное внешнее соединение (FULL JOIN) не поддерживается в MySQL. Можно считать, что это – «избыточная» операция, т.к. она представляется через объединение левого и правого внешних соединений. Например, запрос
С логической точки зрения эти запросы эквивалентны; оба они выводят как дни, когда был и приход, и расход, так и дни, когда отсутствовала одна из операций (отсутствующие значения заменяются NULL). Однако с точки зрения производительности второй запрос проигрывает первому вдвое по оценке стоимости плана. Это связано с тем, что операция UNION приводит к выполнению сортировки, которая отсутствует в плане первого запроса. Сортировка же необходима для процедуры исключения дубликатов, т.к. левое и правое соединения оба содержат строки, соответствующие внутреннему соединению, т.е. случаю, когда есть как приход, так и расход. Поэтому, если вместо UNION написать UNION ALL, то такие строки будут присутствовать в результирующем наборе в двух экземплярах. Тем не менее, чтобы получить план, близкий по стоимости FULL JOIN, нужно избавиться от сортировки. Например, использовать UNION ALL, но в одном из объединяемых запросов исключить строки, соответствующие внутреннему соединению:
Обратите внимание, что заведомо отсутствующие значения, которые появлялись в правом соединении решения (2), здесь формируются явным заданием NULL-значений. Если по каким-то причинам, явное задание NULL вместо соединения вам не подходит, можно оставить соединение, но это даст более дорогой план, хотя и он будет дешевле плана с сортировкой (2):
|