Database
 sql >> Baza danych >  >> RDS >> Database

Liczba odczytanych wierszy / Rzeczywiste ostrzeżenia o odczytaniu wierszy w Eksploratorze planów

Nowa właściwość „Rzeczywiste odczyty wierszy” w planach wykonania (która w SQL Server Management Studio jest wyświetlana jako „Liczba odczytanych wierszy”) była mile widzianym dodatkiem do programów dostrajających wydajność. To jak posiadanie nowej supermocy, aby móc odróżnić znaczenie predykatu Seek od predykatu rezydualnego w ramach operatora Seek. Uwielbiam to, ponieważ może to mieć naprawdę duże znaczenie dla zapytań.

Przyjrzyjmy się dwóm zapytaniom, które uruchamiam w AdventureWorks2012. Są bardzo proste – jedna zawiera listę osób o imieniu John S, a druga to osoby o nazwisku J Smith. Jak wszystkie dobre książki telefoniczne, mamy indeks dotyczący LastName, FirstName.

select FirstName, LastName 
  from Person.Person
  where LastName like 'S%'
  and FirstName = 'John'; 
 
select FirstName, LastName 
  from Person.Person 
  where LastName = 'Smith' 
  and FirstName like 'J%';

Jeśli jesteś ciekawy, cofam 2 rzędy od pierwszego i 14 rzędów z powrotem od drugiego. Właściwie nie interesują mnie wyniki, interesują mnie plany wykonawcze.

Zobaczmy, co się dzieje. Otworzyłem starszą kopię SQL Sentry Plan Explorer i otworzyłem moje plany obok siebie. Nawiasem mówiąc – uruchomiłem oba zapytania razem, więc oba plany znajdowały się w tym samym pliku .sqlplan. Ale mógłbym otworzyć ten sam plik dwa razy w PE i szczęśliwie posadzić je obok siebie w grupach kart.

Świetny. Wyglądają tak samo! Widzę, że Seek po lewej stronie generuje dwa wiersze zamiast czternastu – oczywiście jest to lepsze zapytanie.

Ale przy większym oknie widziałbym więcej informacji i mam szczęście, że uruchomiłem oba zapytania w tej samej partii.

Widać, że drugie zapytanie, które wygenerowało 14 wierszy, a nie 2 wiersze, zostało oszacowane na 80% kosztów! Gdybym uruchomił zapytania osobno, każde z nich pokazałoby mi 100%.

Porównajmy teraz z najnowszą wersją programu Plan Explorer.

Rzeczą, która wyskakuje mi od razu, jest ostrzeżenie. Przyjrzyjmy się trochę bliżej.

Ostrzeżenie mówi:„Operacja spowodowała resztkowe IO. Rzeczywista liczba odczytanych wierszy wyniosła 2130, ale liczba zwróconych wierszy wyniosła 2”. Rzeczywiście, dalej widzimy „Przeczytane wiersze rzeczywiste” z napisem 2130 i wiersze rzeczywiste na poziomie 2.

Łał! Aby znaleźć te wiersze, musieliśmy przejrzeć 2130?

Widzisz, sposób, w jaki działa Seek, polega na zastanowieniu się nad predykatem Seek. To ten, który dobrze wykorzystuje indeks i który faktycznie powoduje, że operacja jest Seek. Bez predykatu wyszukiwania operacja staje się skanowaniem. Teraz, jeśli ten predykat Seek ma co najwyżej jeden wiersz (na przykład, gdy ma operator równości na unikalnym indeksie), to mamy wyszukiwanie Singleton. W przeciwnym razie mamy skanowanie zakresu i ten zakres może mieć przedrostek, początek i koniec (ale niekoniecznie zarówno początek, jak i koniec). To definiuje wiersze w tabeli, które nas interesują dla Seek.

Ale „zainteresowany” niekoniecznie oznacza „zwrócony”, ponieważ możemy mieć więcej pracy do wykonania. Ta praca jest opisana w innym predykacie, który jest często znany jako predykat rezydualny.

Teraz ten Residual Predicate może faktycznie wykonywać większość pracy. Z pewnością jest tutaj – filtruje rzeczy z 2130 wierszy do zaledwie 2.

Range Scan zaczyna się w indeksie od „John S”. Wiemy, że jeśli jest „Jan S”, to musi to być pierwszy rząd, który może zadowolić całość. „Ian S” nie może. W tym momencie możemy przeszukać indeks, aby rozpocząć skanowanie zakresu. Jeśli spojrzymy na Plan XML, możemy to wyraźnie zobaczyć.

Zauważ, że nie mamy prefiksu. Dotyczy to sytuacji, gdy w pierwszej kolumnie indeksu występuje równość. Mamy tylko StartRange i EndRange. Początek zakresu to „Greater Than or Equal” (GE) ScanType, przy wartości „S, John” (odniesienia do kolumn poza ekranem to LastName, FirstName), a koniec zakresu to „Mniej niż” ( LT) wartość T. Kiedy skanowanie dotrze do T, to koniec. Nic więcej do zrobienia. Poszukiwacz zakończył teraz skanowanie zasięgu. A w tym przypadku zwraca 2130 wierszy!

Z wyjątkiem tego, że tak naprawdę nie zwraca 2130 wierszy, po prostu odczytuje 2130 wierszy. Nazwiska takie jak Barry Sai i Ken Sánchez są odczytywane, ale zwracane są tylko te imiona, które spełniają następną weryfikację — orzeczenie rezydualne, które zapewnia, że ​​pierwszym imieniem jest John.

Wpis Actual Rows Read we właściwościach operatora Index Seek pokazuje nam tę wartość 2130. I chociaż jest to widoczne we wcześniejszych wersjach Eksploratora planów, nie otrzymujemy o tym ostrzeżenia. To stosunkowo nowe.

Nasze drugie zapytanie (szukając J. Smitha) jest znacznie ładniejsze i nie bez powodu oszacowano, że jest ponad 4 razy tańsze.

Tutaj dokładnie znamy nazwisko (Smith), a skanowanie zakresu dotyczy imienia (J%).

Tutaj pojawia się prefiks.

Widzimy, że nasz Prefiks jest operatorem równości (=, ScanType=”EQ”), a LastName musi być Smithem. Nie rozważyliśmy jeszcze nawet początku ani końca zakresu, ale prefiks mówi nam, że zakres jest zawarty w części indeksu, w której LastName to Smith. Teraz możemy znaleźć wiersze>=J i

Nadal istnieje tutaj orzeczenie rezydualne, ale jest to tylko upewnienie się, że „LIKE J%” jest rzeczywiście testowane. Chociaż wydaje nam się intuicyjne, że „LIKE J%” jest dokładnie równoważne „>=J i

Przed dodatkiem Service Pack 3 dla programu SQL Server 2012 nie mieliśmy tej właściwości i aby poznać różnicę między rzeczywistymi odczytanymi wierszami a rzeczywistymi wierszami, musielibyśmy użyć flagi śledzenia 9130. Oto te dwa plany z włączonym TF:

Możesz zobaczyć, że tym razem nie ma ostrzeżenia, ponieważ operator Seek zwraca wszystkie 2130 wierszy. Myślę, że jeśli używasz wersji programu SQL Server, która obsługuje ten rzeczywisty odczyt wierszy, powinieneś przestać używać flagi śledzenia 9130 w swoich dochodzeniach i zamiast tego zacząć przeglądać ostrzeżenia w Eksploratorze planów. Ale przede wszystkim zrozum, w jaki sposób Twoi operatorzy robią swoje, ponieważ wtedy będziesz w stanie zinterpretować, czy jesteś zadowolony z planu, czy też musisz podjąć działania.

W innym poście pokażę ci sytuację, w której możesz woleć, aby rzeczywiste odczytane wiersze były wyższe niż rzeczywiste wiersze.

@rob_farley


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak przechowywać harmonogramy pracowników w bazie danych

  2. Nazewnictwo produktów IRI i architektura

  3. Korzyści z indeksowania kluczy obcych

  4. Szybkie znajdowanie odrębnych wartości

  5. Typ danych T-SQL Data/godzina