Эта душа, которую я недавно придумал, и хотя я должен делиться ею:
select top 0
B.*
into
TargetTable
from
SourceTable as A
left join SourceTable as B on 1 = 0
Это эффективно создает дублируемую структуру SourceTable
в TargetTable
, при этом все столбцы обнуляются (по крайней мере, в SQL2008).
Используйте EXPLAIN, чтобы увидеть, как ваша база данных выполняет запрос к вашим данным. В этом ответе есть огромное «это зависит» ...
PostgreSQL может переписать подзапрос в соединение или соединение в подзапрос, если он считает, что один из них быстрее другого. Все зависит от данных, индексов, корреляции, объема данных, запроса и т. Д.
Подзапросы обычно используются для возврата одной строки как атомарного значения, хотя они могут использоваться для сравнить значения с несколькими строками с ключевым словом IN. Они разрешены практически в любой значимой точке оператора SQL, включая целевой список, предложение WHERE и т. Д. В качестве условия поиска можно использовать простой подзапрос. Например, между парой таблиц:
SELECT title FROM books WHERE author_id = (SELECT id FROM authors WHERE last_name = 'Bar' AND first_name = 'Foo');
Обратите внимание, что использование оператора обычного значения для результатов подзапроса требует, чтобы возвращалось только одно поле. Если вас интересует проверка существования одного значения в наборе других значений, используйте IN:
SELECT title FROM books WHERE author_id IN (SELECT id FROM authors WHERE last_name ~ '^[A-E]');
Это явно отличается от, скажем, LEFT-JOIN, где вы просто хотите объединить данные из таблиц A и B даже если условие соединения не находит подходящей записи в таблице B и т. д.
Если вас просто беспокоит скорость, вам придется проверить свою базу данных и написать хороший запрос и посмотреть, есть ли существенная разница в исполнении.
В большинстве случаев запросы JOIN
выполняются быстрее, чем подзапросы, и очень редко подзапросы выполняются быстрее.
В JOIN
СУБД может создать план выполнения, который лучше подходит для вашего запроса и может предсказать, какие данные должны быть загружены для обработки, и сэкономить время, в отличие от подзапроса, в котором он будет выполнять все запрашивает и загружает все свои данные для обработки.
Преимущество подзапросов в том, что они более читабельны, чем запросы JOIN
: вот почему большинство новичков в SQL предпочитают их; это легкий путь; но когда дело доходит до производительности, JOINS в большинстве случаев лучше, хотя их тоже нетрудно читать.
Подзапросы - это логически правильный способ решения проблем формы: «Получить факты от A при условии, что факты от B». В таких случаях логичнее вставить B в подзапрос, чем выполнять соединение. Это также более безопасно в практическом смысле, так как вам не нужно быть осторожным с получением дублированных фактов от A из-за множества совпадений с B.
На практике, однако, ответ обычно сводится к производительности. Некоторые оптимизаторы сосут лимоны, когда им предоставляется соединение с подзапросом, а некоторые - наоборот, и это зависит от оптимизатора, версии СУБД и запроса.
Исторически сложилось так, что явные объединения обычно побеждают, отсюда устоявшееся мнение, что объединения лучше, но оптимизаторы все время становятся лучше, поэтому я предпочитаю сначала писать запросы логически согласованным способом, а затем реструктурировать, если ограничения производительности оправдывают это. .
Прежде всего, для сравнения двух первых нужно различать запросы с подзапросами на:
Для первого класса запросов хорошая РСУБД будет рассматривать джойны и подзапросы как эквивалентные и будет создавать одинаковые планы запросов.
В наши дни даже mysql делает это.
Тем не менее, иногда это не так, но это не значит, что джойны всегда будут выигрывать - у меня были случаи, когда использование подзапросов в mysql улучшало производительность. (Например, если что-то мешает планировщику mysql правильно оценить стоимость и если планировщик не воспринимает join-вариант и subquery-вариант как одно и то же, то подзапросы могут превзойти joins за счет форсирования определенного пути).
Вывод заключается в том, что вы должны тестировать свои запросы для вариантов join и subquery, если вы хотите быть уверены, какой из них будет работать лучше.
Для второго класса сравнение не имеет смысла, так как эти запросы не могут быть переписаны с использованием джойнов, и в этих случаях подзапросы являются естественным способом выполнения требуемых задач, и вы не должны их дискриминировать.