Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Dlaczego jest to skanowanie indeksu, a nie wyszukiwanie indeksu?

Używa skanowania indeksu głównie dlatego, że używa również łączenia scalającego. Operator Merge Join wymaga dwóch strumieni wejściowych, które są posortowane w kolejności zgodnej z warunkami Join.

I używa operatora Merge Join, aby zrealizować swoje INNER JOIN, ponieważ uważa, że ​​będzie to szybsze niż bardziej typowy operator Nested Loop Join. I prawdopodobnie ma rację (zazwyczaj tak), używając dwóch wybranych indeksów, ma strumienie wejściowe, które są wstępnie posortowane zgodnie z warunkiem przyłączenia (LocationID). Gdy strumienie wejściowe są wstępnie posortowane w ten sposób, połączenia scalające są prawie zawsze szybsze niż pozostałe dwa (połączenia pętli i mieszania).

Wadą jest to, co zauważyłeś:wydaje się, że skanuje cały indeks, więc jak to może być szybsze, jeśli odczytuje tak wiele rekordów, których nigdy nie można użyć? Odpowiedź jest taka, że ​​Skany (ze względu na ich sekwencyjny charakter) mogą czytać od 10 do 100 razy więcej rekordów na sekundę niż szuka.

Teraz wyszukiwania zwykle wygrywają, ponieważ są selektywne:otrzymują tylko wiersze, o które prosisz, podczas gdy skanowanie nie jest selektywne:muszą zwracać każdy wiersz w zakresie. Ale ponieważ Skany mają dużo wyższa szybkość odczytu, często mogą pokonać Seeks, o ile stosunek odrzuconych wierszy do pasujących wierszy jest niższy niż stosunek liczby wierszy skanowania/s vs. Szukaj wierszy/s.

Pytania?

OK, poproszono mnie o dokładniejsze wyjaśnienie ostatniego zdania:

„Odrzucony wiersz” to taki, który czyta skan (ponieważ musi odczytać wszystko w indeksie), ale zostanie odrzucony przez operator Merge Join, ponieważ nie ma dopasowania po drugiej stronie, prawdopodobnie dlatego, że Warunek klauzuli WHERE już ją wykluczył.

„Dopasowane wiersze” to te, które odczytuje, a które są faktycznie dopasowane do czegoś w sprzężeniu scalającym. Są to te same wiersze, które zostałyby odczytane przez Seek, gdyby skanowanie zostało zastąpione Seek.

Możesz dowiedzieć się, jakie są, patrząc na statystyki w Planie zapytań. Widzisz tę ogromną, grubą strzałkę po lewej stronie Skanowania Indeksu? To reprezentuje liczbę wierszy, które optymalizator myśli, że odczyta za pomocą skanowania. Pole statystyk w opublikowanym skanowaniu indeksu pokazuje, że faktycznie zwróconych wierszy wynosi około 5,4 mln (5 394 402). To jest równe:

TotalScanRows = (MatchingRows + DiscardedRows)

(W każdym razie według mnie). Aby uzyskać pasujące wiersze, spójrz na „Rzeczywiste wiersze” zgłaszane przez operatora Merge Join (być może będziesz musiał zdjąć TOP 100, aby uzyskać to dokładnie). Gdy już to wiesz, możesz uzyskać wiersze Odrzucone przez:

DiscardedRows = (TotalScanRows - MatchingRows)

A teraz możesz obliczyć stosunek.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy zwracana wartość 0 jest zawsze sukcesem w procedurach składowanych?

  2. Link do SQL ForeignKeyReferenceAlreadyHasValueException

  3. SQL Server i luki w kolumnie tożsamości

  4. Wstaw podwójne cudzysłowy do danych wyjściowych SQL

  5. Zapytanie SQL - Wybierz * z widoku lub Wybierz col1, col2, ... colN z widoku