La tabella ha una chiave primaria. Usalo.
Invece di LIMIT
e OFFSET
, esegui il tuo paging con un filtro sulla chiave primaria. Hai accennato a questo con il tuo commento:
Cercapersone utilizzando numeri casuali (aggiungi "MAGGIORE DI ORDINA PER" a ciascuna query)
ma non c'è niente di casuale su come dovresti farlo.
SELECT * FROM big_table WHERE id > $1 ORDER BY id ASC LIMIT $2
Consenti al client di specificare entrambi i parametri, l'ultimo ID visualizzato e il numero di record da recuperare. La tua API dovrà avere un segnaposto, un parametro aggiuntivo o una chiamata alternativa per "recupera il prima n IDs" dove omette il WHERE
clausola dalla query, ma è banale.
Questo approccio utilizzerà una scansione dell'indice abbastanza efficiente per mettere in ordine i record, evitando generalmente un ordinamento o la necessità di scorrere tutti i record ignorati. Il cliente può decidere quante righe desidera contemporaneamente.
Questo approccio differisce da LIMIT
e OFFSET
approccio in un modo chiave:modifica simultanea. Se INSERT
nella tabella con un tasto inferiore rispetto a una chiave che alcuni client hanno già visto, questo approccio non cambierà affatto i suoi risultati, mentre OFFSET
approccio ripeterà una riga. Allo stesso modo, se DELETE
una riga con un ID inferiore a quello già visto i risultati di questo approccio non cambieranno, mentre OFFSET
salterà una riga invisibile. Tuttavia, non vi è alcuna differenza per le tabelle di sola aggiunta con chiavi generate.
Se sai in anticipo che il cliente vorrà l'intero set di risultati, la cosa più efficiente da fare è semplicemente inviare loro l'intero set di risultati senza queste attività di paging. Ecco dove vorrei usa un cursore. Leggere le righe dal DB e inviarle al client alla velocità con cui il client le accetterà. Questa API avrebbe bisogno di impostare limiti sulla lentezza del client per evitare un carico di back-end eccessivo; per un client lento, probabilmente passerei al paging (come descritto sopra) o farei lo spooling dell'intero risultato del cursore in un file temporaneo e chiuderei la connessione DB.
Avvertenze importanti :
- Richiede un
UNIQUE
vincolo /UNIQUE
index oPRIMARY KEY
essere affidabile - Diverso comportamento di modifica simultanea per limitare/compensare, vedi sopra