Mysql
 sql >> Database >  >> RDS >> Mysql

mySQL - Impaginazione di righe filtrate

Non puoi sapere quale sia il primo ID su una determinata pagina, perché i numeri ID non sono necessariamente sequenziali. In altre parole, potrebbero esserci delle lacune nella sequenza, quindi le righe sulla quinta pagina di 100 righe non iniziano necessariamente con id 500. Potrebbe iniziare con id 527, ad esempio, è impossibile da sapere.

Detto ancora in un altro modo:id è un valore, non un numero di riga.

Una possibile soluzione se il tuo client avanza attraverso le pagine in ordine crescente è che ogni richiesta REST recuperi i dati, osserva il più grande id in quella pagina, quindi utilizza quello nel successivo Richiesta REST in modo che interroghi i valori id più grandi.

SELECT ... FROM ... WHERE filterKey = filterValue 
AND id > id_of_last_match_of_previous_page

Ma se la tua richiesta REST può recuperare qualsiasi pagina casuale, questa soluzione non funziona. Dipende dall'aver già recuperato la pagina precedente.

Un'altra soluzione consiste nell'usare LIMIT <x> OFFSET <y> sintassi. Ciò ti consente di richiedere qualsiasi pagina arbitraria. LIMIT <y>, <x> funziona allo stesso modo, ma per qualche motivo xey sono invertiti nelle due diverse forme di sintassi, quindi tienilo a mente.

Usando LIMIT...OFFSET non è molto efficiente quando richiedi una pagina che contiene molte pagine nel risultato. Supponiamo che tu richieda la 5.000a pagina. MySQL deve generare un risultato sul lato server di 5.000 pagine, quindi scartarne 4.999 e restituire l'ultima pagina nel risultato. Scusa, ma è così che funziona.

Re il tuo commento:

Devi capire che WHERE applica condizioni su valori in righe, ma le pagine sono definite dalla posizione di righe. Questi sono due modi diversi per determinare le righe!

Se hai una colonna che è garantita come un numero di riga , quindi puoi utilizzare quel valore come una posizione di riga. Puoi anche inserire un indice o usarlo come chiave primaria.

Tuttavia, i valori della chiave primaria possono cambiare e non essere consecutivi, ad esempio se si aggiorna o si eliminano righe o si ripristinano alcune transazioni e così via. La rinumerazione dei valori delle chiavi primarie è una cattiva idea perché altre tabelle o dati esterni potrebbero fare riferimento ai valori delle chiavi primarie.

Quindi potresti aggiungere un'altra colonna che non è la chiave primaria, ma solo un numero di riga.

ALTER TABLE MyTable ADD COLUMN row_number BIGINT UNSIGNED, ADD KEY (row_number);

Quindi riempi i valori quando devi rinumerare le righe.

SET @row := 0;
UPDATE MyTable SET row_number = (@row := @row + 1) ORDER BY id;

Dovresti rinumerare le righe se ne elimini alcune, ad esempio. Non è efficiente farlo frequentemente, a seconda delle dimensioni del tavolo.

Inoltre, i nuovi inserimenti non possono creare valori di numero di riga corretti senza bloccare la tabella. Ciò è necessario per evitare condizioni di gara.

Se hai una garanzia che row_number è una sequenza di valori consecutivi, quindi è sia un valore che una posizione di riga, quindi puoi usarlo per ricerche di indici ad alte prestazioni per qualsiasi pagina arbitraria di righe.

SELECT * FROM MyTable WHERE row_number BETWEEN 401 AND 500;

Almeno fino alla prossima volta che la sequenza dei numeri di riga viene messa in dubbio da una cancellazione o da nuovi inserimenti.