Jak to robisz LIMIT
w DB2 for iSeries?
Mam tabelę zawierającą ponad 50 000 rekordów i chcę zwrócić rekordy od 0 do 10 000 i rekordy od 10 000 do 20 000.
Wiem, że w SQL piszesz LIMIT 0,10000
na końcu zapytania od 0 do 10000 a LIMIT 10000,10000
na końcu zapytania od 10000 do 20 000
Jak więc to się robi w DB2? Jaki jest kod i składnia? (przykład pełnego zapytania jest mile widziany)
db2
limit
ibm-midrange
elcool
źródło
źródło
Odpowiedzi:
Używając
FETCH FIRST [n] ROWS ONLY
:http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.perf/db2z_fetchfirstnrows.htm
Aby uzyskać zakresy, musisz użyć
ROW_NUMBER()
(od wersji v5r4) i użyć tego wWHERE
klauzuli: (skradzione stąd: http://www.justskins.com/forums/db2-select-how-to-123209.html )źródło
ROW_NUMBER
nie jest prawidłowym słowem kluczowym. Ale dzięki za link, dał mi pomysł i działa.Opracował tę metodę:
POTRZEBUJESZ tabeli, która ma unikalną wartość, którą można zamówić.
Jeśli chcesz uzyskać wiersze od 10 000 do 25 000, a Twoja tabela ma 40 000 wierszy, najpierw musisz uzyskać punkt początkowy i całkowitą liczbę wierszy:
int start = 40000 - 10000;
int total = 25000 - 10000;
A następnie przekaż je kodem do zapytania:
źródło
Wsparcie dla OFFSET i LIMIT zostało ostatnio dodane do DB2 for i 7.1 i 7.2. Aby uzyskać tę obsługę, potrzebne są następujące poziomy grup DB PTF:
Więcej informacji można znaleźć tutaj: dokumentacja OFFSET i LIMIT , DB2 for i Enhancement Wiki
źródło
Oto rozwiązanie, które wymyśliłem:
Poprzez zainicjowanie LASTVAL na 0 (lub „” dla pola tekstowego), a następnie ustawienie ostatniej wartości w najnowszym zestawie rekordów, spowoduje to przejście przez tabelę w fragmentach N rekordów.
źródło
N
jest mniejsza niż liczba identycznych wartości w kolumnie (chociaż jest to prawdą również w przypadku użyciaROW_NUMBER()
). Wartości początkowe również należy dobierać ostrożnie -0
oczywiście będzie to problematyczne, jeśli kolumna zawiera wartość ujemną . Konieczna będzie ostrożność w przypadku wartości zerowych. Nie będzie działać, jeśli strony zostaną pominięte.Rozwiązanie @ elcool to sprytny pomysł, ale musisz znać całkowitą liczbę wierszy (która może nawet ulec zmianie podczas wykonywania zapytania!). Proponuję więc zmodyfikowaną wersję, która niestety wymaga 3 podzapytań zamiast 2:
gdzie
{last}
powinien zostać zastąpiony numerem wiersza ostatniego potrzebnego rekordu, a{length}
liczbą potrzebnych wierszy, obliczoną jakolast row - first row + 1
.Np. Jeśli chcę rzędy od 10 do 25 (łącznie 16 rzędów),
{last}
będzie 25 i{length}
będzie 25-10 + 1 = 16.źródło
Należy również wziąć pod uwagę klauzulę OPTIMIZE FOR n ROWS. Więcej szczegółów na ten temat w dokumentacji DB2 LUW w temacie Wytyczne dotyczące ograniczania instrukcji SELECT :
źródło
Spróbuj tego
źródło
Istnieją 2 sposoby wydajnego dzielenia stron na strony w tabeli DB2:
1 - technika wykorzystująca funkcję row_number () i klauzulę OVER, która została zaprezentowana w innym poście ("SELECT row_number () OVER (ORDER BY ...)"). Na niektórych dużych stołach zauważyłem czasami degradację występów.
2 - technika wykorzystująca przewijany kursor. Implementacja zależy od używanego języka. Ta technika wydaje się solidniejsza na dużych stołach.
Przedstawiłem 2 techniki wdrożone w PHP na seminarium w przyszłym roku. Slajd jest dostępny pod tym linkiem: http://gregphplab.com/serendipity/uploads/slides/DB2_PHP_Best_practices.pdf
Przepraszamy, ale ten dokument jest tylko w języku francuskim.
źródło
Tam są dostępne opcje: -
źródło