Первое лучше, потому что оно логически связно. Условие области действия не имеет отношения к соединению, поэтому включение его в состав соединения является кладжем, и в данном случае бесполезным.
В реляционной алгебре нет никакой разницы. Такие критерии, как место и внутреннее соединение, взаимозаменяемы. Я использую и то, и другое в зависимости от читабельности и ситуации.
В этом конкретном случае вы также можете использовать:
select person.* from person WHERE person.roleid = @Roleid
Единственная разница в том, что для этого не требуется наличие строки в таблице ролей (но я предполагаю, что у вас есть ссылочная целостность для этого), и он не вернет несколько строк, если roleid не уникален (что почти наверняка так и есть в большинстве сценариев, которые я мог предвидеть).
Лучше всего попробовать эти запросы и прогнать их через план выполнения MS Sql. Я сделал это, и результаты выглядят так:
Как видите, производительность такая же ( разрешено, запуск его в вашей базе данных может дать разные результаты. ) Итак, лучший запрос - это тот, который следует согласованному соглашению, которое вы используете для написания запросов.
SQL Server должен одинаково оценивать эти запросы. Лично я бы использовал AND. Мне нравится хранить все критерии для объединенной таблицы в самом объединении, чтобы их было легко найти.
Оба запроса идентичны. Во время обработки запроса SQL-сервер применяет фильтр WHERE сразу после применения фильтра условия соединения, так что вы получите те же самые вещи, отфильтрованные в любом случае.
Я предпочитаю № 1, я считаю, что он лучше выражает цель утверждения. Вы объединяете две таблицы на основе roleid и role.id и фильтруете на основе @Roleid
SELECT person.*
FROM person INNER JOIN role ON person.roleid = role.id
Where role.id = @Roleid
Поскольку вы не выбираете столбцы из роли
, вам лучше вообще не включать ее в предложение FROM
. Используйте это:
SELECT *
FROM person
WHERE person.roleid IN (SELECT id FROM role WHERE id = @Roleid)
Таким образом, оптимизатор видит только одну таблицу в предложении FROM
и может быстро определить количество элементов набора результатов (то есть количество строк в наборе результатов <= количество строк в таблице person
).
Когда вы бросаете две таблицы с JOIN
, оптимизатор должен посмотреть в предложении ON
, чтобы выяснить, являются ли эти таблицы равносвязаны и существуют ли уникальные индексы для объединенных столбцов. Если предикат в предложении ON
является сложным (несколько операторов AND и OR) или просто неверным (иногда очень неправильным), оптимизатор может выбрать неоптимальную стратегию соединения.
Я бы пошел с первый, но помните, что по завершении тестирования кода вы должны явно выбрать каждую таблицу, вместо того, чтобы делать select *
Sqlserver, вероятно, имеет эквивалент оператора «плана объяснения», который Oracle, PostgreSQL и MySQL поддерживают в той или иной форме. Это может быть очень полезно, рассказывая вам, как анализатор и оптимизатор запросов будут обрабатывать ваш запрос.
Произойдет ли какое-либо снижение / увеличение производительности при использовании этого запроса?
SELECT person.* FROM person,role WHERE person.roleid=role.id AND role.id=@RoleID