Поскольку у вас есть два набора данных, упорядоченных по одному и тому же значению .. вы пытались объединить объединение вместо вложенного цикла?
SET STATISTICS IO ON
SET STATISTICS TIME ON
SELECT COUNT(*)
FROM Address adr INNER JOIN
Auditable a on adr.UniqueId = a.UniqueId
OPTION (LOOP JOIN)
SELECT COUNT(*)
FROM Address adr INNER JOIN
Auditable a on adr.UniqueId = a.UniqueId
OPTION (MERGE JOIN)
SELECT COUNT(*)
FROM Address adr INNER JOIN
Auditable a on adr.UniqueId = a.UniqueId
OPTION (HASH JOIN)
Edit:
Эти объяснения являются концептуальными. SQL Server может выполнять более сложные операции, чем показывают мои примеры. Это концептуальное понимание, сопоставимое с измерением времени и логическим IO с помощью команд SET STATISTICS, и рассмотрение планов выполнения запросов - формирует основу моего метода оптимизации запросов (выращенного в течение четырех лет). Пусть он послужит вам так же хорошо, как и он.
Настройка
- Получите 5 колод карт.
- Возьмите 1 колоду и создайте родительский набор данных.
- Возьмите остальные 4 колоды и создайте набор данных для детей.
- Закажите каждый набор данных по значению карты.
- Пусть m - количество карточек в родительском наборе данных.
- Пусть n - количество карточек в наборе данных для детей.
NestedLoop
- Возьмите карту с верхней частью набора родительских данных.
- Поиск (с использованием двоичного поиска) в наборе данных для первого совпадения.
- Ищите вперед в наборе данных ребенка из первого совпадения до тех пор, пока не будет найден несоответствие. Теперь вы нашли все матчи.
- Повторите это для каждой карты в родительском наборе данных.
вложенной итерации алгоритма цикла набор данных родитель, а затем ищет данные ребенка, установленные один раз для каждого родителя, что делает его стоимость: м * журнал (п)
Объединить
- Take карту с верхней части родительского набора данных.
- Возьмите карту с верхней части набора данных для детей.
- Если карты совпадают, потяните карты из верхней части каждой колоды, пока между ними не будет найдена несоответствие. Производите каждую соответствующую пару между родительским и дочерним совпадениями.
- Если карты не совпадают, найдите меньше между родительской и дочерней картами и возьмите карту с верхней части этого набора данных.
Алгоритм слияния объединяет один и тот же родительский набор данных и один раз устанавливает дочерние данные, что делает его стоимость: m + n. Он полагается на данные, которые заказываются. Если вы попросите присоединиться к объединению по не заказанным данным, вы понесете операцию заказа! Это приводит к стоимости (m * log (m)) + (n * log (n)) + m + n. Даже в некоторых случаях это может быть лучше, чем вложенный цикл.
Hash
- Получить карточный стол.
- Возьмите каждую карту из родительского набора данных и поместите ее на карточный стол, где вы можете его найти (не обязательно иметь какое-либо отношение к стоимости карты, просто должно быть удобно для вас).
- Возьмите каждую карту из набора данных для детей, найдите соответствующий столбец на картоном столе и создайте соответствующую пару.
Алгоритм хеш-объединения выполняет итерацию родительского набора данных один раз, а дочерние данные устанавливаются один раз, что делает его стоимостью: m + n. Он полагается на наличие достаточно большой карточной таблицы для хранения всего содержимого родительского набора данных.
Что такое «долгое время», есть ли у вас план выполнения запроса? Можете ли вы предоставить схему для таблиц? Если его хорошо проиндексировать, как вы говорите, нет никаких оснований для этого в любое время. –
Можете ли вы предоставить какие-либо сведения о плане запроса? (например, скриншот из SQL Server Management Studio или плана XML). Также, какая доля адресов имеет базовую аудиторию? –
Вы пробовали выбрать один из индексированных столбцов? В прежние времена было быстрее сказать COUNT (adr.uniqueid), потому что он мог читать все, что вам нужно, из индекса, и никогда не приходил к самому столу. Я бы попробовал это. Также проверьте, обновляется ли статистика на столе. – MJB