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ż uruchomienieWHERE/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 prostymSELECT 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)
iROW_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...
- Bardziej wydajna metoda stronicowania przez duże zestawy wyników
- Optymalizacja stronicowania po stronie serwera – część I
- Optymalizacja stronicowania po stronie serwera – część II
- Wyjaśnienie sumy Gaussa
- Zwracanie wyników rankingowych za pomocą Microsoft SQL Server 2005
- ROW_NUMBER() OVER Niewystarczająco szybko z dużym zestawem wyników
- Pobieranie pierwszych rekordów N z zapytania SQL
- Stronicowanie po stronie serwera przy użyciu SQL Server 2005
- Dlaczego są tak wysokie odczyty logiczne dla okienkowych funkcji agregujących?
Mam nadzieję, że to pomoże.