Krótka odpowiedź: ponieważ optymalizator uważa byłoby szybciej.
Spróbujmy jednak przeczytać umysł optymalizatora.
Ponieważ nie podano pełnego schematu tabeli, zakładam, że istnieje indeks klastrowany na xxx.ID
i że #TaxInvoiceData
jest stertą. Oczekujesz planu, w którym indeks PK jest badany dla każdego wiersza w #TaxInvoiceData
, ale wybierasz xxx.Field4
, który będzie wymagał wyszukiwania zakładek dla każdego dopasowania. Może to spowodować 29 000 losowych żądań we/wy. Oooo.
Odwrotnie, SQL Server może (i najwyraźniej będzie) wykonać większą liczbę bardziej wydajnych operacji wejścia/wyjścia, wykonując skanowanie tabeli i prawdopodobnie wykona szybki skrót z #TaxInvoiceData
.
Co więc można zrobić? Możesz utworzyć indeks obejmujący Field4
. Lub możesz użyć indeksu i dołączyć wskazówki, aby wymusić plan, którego szukasz (ale podejrzewam, że wydajność nie byłaby tak dobra, jak masz nadzieję). Czy to zapytanie jest używane na tyle często, że daje problemy z wydajnością aplikacji lub po prostu chcesz wyeliminować skanowanie tabeli z zasady? Jeśli to drugie, może się okazać, że narzut pozbycia się skanu nie jest w końcu wart.
Edit:
Skoro już wspomniałem, że nie ma indeksu klastrowego na stole, to również może mieć wpływ na sposób efektywny wyszukiwań z indeksu są. Jeśli ta tabela nie jest bardzo obciążona, należy rozważyć zmianę PK w klastrze. Już samo to może zmienić plan, a nawet jeśli nie przyspieszy innych operacji z powodu zmniejszenia narzutów.
Ile wierszy jest w #TaxInvoiceData? – Joe
* Czy indeks wyszukiwania * - ok, ale na ** który indeks ** ??? Ponadto: mówisz '(ID, Field2, Field3)' są kluczem podstawowym twojego 'Table X' - czy ** indeks klastrowany ** również jest w tabeli? Czy to jest kupa? –
W jaki sposób S dołącza do zapytania? Możliwe, że ponieważ klucz podstawowy nie jest klastrowany, szybsze jest przeskanowanie tabeli niż przeskok między indeksem a tabelą dla każdego wiersza. – idstam