Краткий ответ: потому что оптимизатор считает, что это будет быстрее.
Однако давайте попробуем прочитать мысли оптимизатора.
Поскольку вы не предоставили полную схему таблиц, я собираюсь предположить, что в xxx.ID
есть кластеризованный индекс, а #TaxInvoiceData
- это куча. Вы ожидаете план, в котором индекс PK будет проверяться для каждой строки в #TaxInvoiceData
, но вы выбираете xxx.Field4
, что потребует поиска закладок для каждого совпадения. Это может привести к 29 000 случайных запросов ввода-вывода. Уч.
И наоборот, SQL Server может (и, по-видимому, собирается) просто выполнить больший объем более эффективных последовательных операций ввода-вывода, выполняя сканирование таблицы, и, вероятно, выполняет быстрое сопоставление хеша с #TaxInvoiceData
.
Так что вы можете сделать? Вы можете создать индекс покрытия, включая Field4
. Или вы могли бы использовать подсказки index и join для форсирования плана, который вы ищете (но я подозреваю, что производительность будет не такой хорошей, как вы надеетесь). Используется ли этот запрос достаточно часто, чтобы он вызывал проблемы с производительностью вашего приложения, или вы просто хотите исключить сканирование таблиц в принципе? Если последнее, вы можете обнаружить, что затраты на избавление от сканирования в итоге не стоят.
Edit:
Поскольку вы упомянули, что в таблице нет кластеризованного индекса, это также может повлиять на эффективность поиска по индексу. Если в этой таблице не наблюдается очень интенсивная операция вставки, рассмотрите возможность изменения вашего ПК на кластерный. Одно это может изменить план, и даже если это не так, он может ускорить другие операции из-за сокращения накладных расходов.