sql >> Database >  >> RDS >> PostgreSQL

Hoe een API-client te voorzien van 1.000.000 databaseresultaten?

De tabel heeft een primaire sleutel. Maak er gebruik van.

In plaats van LIMIT en OFFSET , voer uw paging uit met een filter op de primaire sleutel. Je hintte hierop met je opmerking:

Paging met behulp van willekeurige getallen (Voeg "GREATER THAN ORDER BY" toe aan elke query)

maar er is niets willekeurigs aan hoe je het zou moeten doen.

SELECT * FROM big_table WHERE id > $1 ORDER BY id ASC LIMIT $2

Laat de klant beide parameters specificeren, de laatste ID die hij heeft gezien en het aantal records dat moet worden opgehaald. Uw API moet ofwel een tijdelijke aanduiding, een extra parameter of een alternatieve aanroep hebben voor "fetch the first n ID's" waar het de WHERE . weglaat clausule uit de query, maar dat is triviaal.

Deze aanpak maakt gebruik van een redelijk efficiënte indexscan om de records op orde te krijgen, waarbij in het algemeen een sortering of de noodzaak om alle overgeslagen records te doorlopen wordt vermeden. De klant kan beslissen hoeveel rijen hij tegelijk wil.

Deze aanpak verschilt van de LIMIT en OFFSET benadering op één belangrijke manier:gelijktijdige wijziging. Als u INSERT in de tabel met een toets lager dan een sleutel die een klant al heeft gezien, zal deze benadering de resultaten helemaal niet veranderen, terwijl de OFFSET aanpak zal een rij herhalen. Evenzo, als u DELETE een rij met een lager dan al eerder gezien ID, zullen de resultaten van deze aanpak niet veranderen, terwijl OFFSET zal een onzichtbare rij overslaan. Er is echter geen verschil voor alleen-toevoegen-tabellen met gegenereerde sleutels.

Als je van tevoren weet dat de klant de hele resultatenset wil, is het meest efficiënte wat je kunt doen, hem de hele resultatenset sturen zonder al die paging-activiteiten. Dat is waar ik zou gebruik een cursor. Lees de rijen uit de DB en stuur ze naar de client zo snel als de client ze accepteert. Deze API zou limieten moeten stellen aan hoe traag de client mocht zijn om overmatige backend-belasting te voorkomen; voor een langzame client zou ik waarschijnlijk overschakelen naar paging (zoals hierboven beschreven) of het hele cursorresultaat naar een tijdelijk bestand spoolen en de DB-verbinding sluiten.

Belangrijke waarschuwingen :

  • Vereist een UNIQUE beperking / UNIQUE index of PRIMARY KEY betrouwbaar zijn
  • Verschillend gelijktijdig wijzigingsgedrag tot limiet/compensatie, zie hierboven


  1. Zelfstudie Microsoft TreeView Control

  2. Gegevens exporteren uit een MySQL-database

  3. Hoe bestanden te verwijderen in SQL Server 2019

  4. Zijn geneste transacties toegestaan ​​in MySQL?