PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come fornire a un client API 1.000.000 di risultati di database?

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 o PRIMARY KEY essere affidabile
  • Diverso comportamento di modifica simultanea per limitare/compensare, vedi sopra