«Отсканировано только один раз» немного вводит в заблуждение. Сканирование таблиц - ужасно дорогая вещь в SQL Server. По крайней мере до SS2005 сканирование таблицы требует чтения всех строк во временной таблице, а затем чтения временной таблицы, чтобы найти строки, соответствующие условию соединения. Таким образом, в худшем случае ваш запрос будет читать и записывать 1M строк, затем пытаться сопоставить 2 строки с 1M строк, а затем удалять временную таблицу (этот последний бит, вероятно, самая дешевая часть запроса). Так что если на B нет пригодных для использования индексов, вы просто в плохом месте.
Во втором примере, если B.Xyz не проиндексирован, происходит полное сканирование таблицы и , имеется вторичное совпадение от 2 до 1000 строк, что даже менее эффективно. Если B.Xyz проиндексирован , должен быть выполнен поиск по индексу и соответствие 2: 1000 - гораздо быстрее и эффективнее.
'Конечно, это предполагает, что статистика таблиц относительно актуальна, и никакие опции не влияют на работу оптимизатора.
РЕДАКТИРОВАНИЕ: возможно ли для вас "развернуть" строки A и использовать их в качестве статического условия в запросе no-JOIN на B? Мы использовали это в нескольких местах в нашем приложении, где мы объединяем маленькие таблицы (<100 строк) и большие (> 100M строк), чтобы получить отличный эффект.