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

Wydajny sposób na uzyskanie @@rowcount z zapytania przy użyciu numeru_wiersza

Z biegiem lat stos potu programistów pochłonął wydajne stronicowanie zestawów wyników. Jednak nie ma jednej odpowiedzi — zależy to od przypadku użycia. Częścią przypadku użycia jest wydajne tworzenie strony, częścią jest ustalenie, ile wierszy znajduje się w pełnym zestawie wyników. Bardzo przepraszam, jeśli trochę zabłąkam się w stronę stronicowania, ale w moim umyśle są one dość mocno powiązane.

Istnieje wiele strategii, z których większość jest zła, jeśli masz jakąkolwiek ilość danych i nie pasujesz do przypadku użycia. Chociaż nie jest to pełna lista, poniżej przedstawiono niektóre z opcji.....

Uruchom oddzielny Count(*)

  • uruchom osobne zapytanie, które wykonuje proste „wybierz liczbę(*) z Mojej tabeli”
  • proste i łatwe na mały stolik
  • dobre na niefiltrowanej dużej tabeli, która jest albo wąska, albo ma zwarty indeks nieklastrowany, którego można użyć
  • załamuje się, gdy masz skomplikowane WHERE/JOIN kryteria, ponieważ uruchomienie WHERE/JOIN dwa razy jest drogie.
  • rozkłada się według szerokiego indeksu, ponieważ liczba odczytów rośnie.

Połącz ROW_Number() OVER() i COUNT(1) OVER(PARTITION By 1)

  • Zasugerował to @RBarryYoung. Ma tę zaletę, że jest prosty w implementacji i bardzo elastyczny.
  • Wadą jest to, że istnieje wiele powodów, dla których może to szybko stać się niezwykle kosztowne.
  • Na przykład w bazie danych, w której aktualnie pracuję, znajduje się tabela Media z około 6000 wierszami. Nie jest szczególnie szeroki, ma skupioną liczbę całkowitą PK, a także zwarty unikalny indeks. Jednak proste COUNT(*) OVER(PARTITION BY 1) as TotalRows wyniki w ~12 000 odczytów. Porównaj to z prostym SELECT COUNT(*) FROM Media - 12 odczytów. Wowzery.

Tabele temperatur / Zmienne tabel

  • Istnieje wiele strategii, które pobierają zestaw wyników i wstawiają odpowiednie klucze lub segmenty wyników do tabel tymczasowych / zmiennych tabeli.
  • Dla małych/średnich zestawów wyników może to zapewnić wspaniałe rezultaty.
  • Ten rodzaj strategii działa na prawie każdej platformie/wersji SQL.
  • Operowanie na zestawie wyników wielokrotne (dość często wymaganie) jest również łatwe.
  • Wadą jest praca z dużymi zestawami wyników... wstawienie kilku milionów wierszy do tabeli tymczasowej ma swój koszt.
  • Pokładając problem, w systemie o dużej objętości ciśnienie na TempDB może być sporym czynnikiem, a tabele temp skutecznie działają w TempDB.

Suma Gaussa / numer dwurzędowy

  • Ten pomysł opiera się na podzbiorze czegoś, co odkrył matematyk Gauss (jak zsumować szereg liczb). Podzbiór polega na tym, jak uzyskać liczbę wierszy z dowolnego punktu w tabeli.
  • Z serii liczb (Row_Number() ) liczba wierszy od 1 do N wynosi (N + 1) - 1 . Więcej wyjaśnień w linkach.
  • Wygląda na to, że formuła miałaby tylko N, ale jeśli będziesz trzymać się formuły, wydarzy się coś ciekawego, możesz obliczyć liczbę wierszy na stronie pośrodku tabeli.
  • Wynikiem netto jest wykonanie ROW_Number() OVER(Order by ID) i ROW_Number() OVER(Order by ID DESC) następnie zsumuj te dwie liczby i odejmij 1.
  • Używając mojej tabeli Media jako przykładu, moje odczyty spadły z 12 000 do około 75.
  • Na większej stronie wielokrotnie powtarzałeś dane, ale przesunięcie w odczytach może być tego warte.
  • Nie testowałem tego na zbyt wielu scenariuszach, więc może się rozpaść w innych scenariuszach.

Góra (@n) / USTAWIĆ WIERSZ

  • Nie są to konkretne strategie per se, ale optymalizacje oparte na tym, co wiemy o optymalizatorze zapytań.
  • Twórcze użycie Top(@n) [top może być zmienną w SQL 2008] lub SET ROWCOUNT może zredukować twój zestaw roboczy ... nawet jeśli wyciągasz środkową stronę zestawu wyników, nadal możesz zawęzić wynik
  • Te pomysły działają z powodu zachowania optymalizatora zapytań ... dodatek Service Pack/poprawka może zmienić zachowanie (choć prawdopodobnie nie).
  • W niektórych przypadkach SET ROWCOUNT może być nieco dokładny
  • Ta strategia nie uwzględnia uzyskania pełnej liczby wierszy, po prostu zwiększa wydajność stronicowania

Co więc ma zrobić programista?

Przeczytaj mój dobry człowieku, przeczytaj. Oto kilka artykułów, na których się opierałem...

Mam nadzieję, że to pomoże.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ukrywanie instancji SQL Server w sieci

  2. Niewiarygodny duplikat w Entity Framework Query

  3. Przykłady formatowania „datetimeoffset” w SQL Server przy użyciu standardowych ciągów formatujących (T-SQL)

  4. Zdezorientowany UPDLOCK, HOLDLOCK

  5. Co robi 'COLLATE SQL_Latin1_General_CP1_CI_AS'?