Dit is wat ik heb gedaan en de totale uitvoeringstijd met een factor 10 heb verminderd.
Wat ik me realiseerde uit het uitvoeringsplan van mijn oorspronkelijke query, was dat het filesort gebruikte voor het sorteren van alle resultaten en het negeren van de indexen. Dat is een beetje zonde.
Mijn testdatabase:5 M records, 20 GB groot. tabelstructuur hetzelfde als in de vraag
In plaats van blobCol direct in de eerste query te krijgen, krijg ik eerst de waarde van 'name' voor het begin van elke pagina. Voer deze query voor onbepaalde tijd uit totdat deze 0 resultaten oplevert. Voeg elke keer het resultaat toe aan een lijst
SELECT name
FROM my_table
where id = <anyId> // I use the id column for partitioning so I need this here
order by name
limit <pageSize * pageNumber>, 1
Het paginanummer van de sinus is niet eerder bekend, begin met waarde 0 en blijf verhogen totdat de query null retourneert. Je kunt ook een select count(*) doen, maar dat kan op zich lang duren en zal niet helpen om iets te optimaliseren. Elke zoekopdracht duurde ongeveer 2 seconden om uit te voeren zodra het paginanummer ~60 overschreed.
Voor mij was de paginagrootte 5000, dus ik kreeg een lijst met 'naam'-strings op positie 0, 5001, 10001, 15001 enzovoort. Het aantal pagina's bleek 1000 te zijn en het opslaan van een lijst van 1000 resultaten in het geheugen is niet duur.
Herhaal nu de lijst en voer deze zoekopdracht uit
SELECT blobCol
FROM my_table
where name >= <pageHeader>
and name < <nextPageHeader>
and city="<any string>"
and id= 1
Dit wordt N keer uitgevoerd, waarbij N =grootte van eerder verkregen lijst. Aangezien 'naam' de primaire sleutel is en 'stad' ook geïndexeerd is, laat EXPLAIN zien dat deze berekening in het geheugen wordt uitgevoerd met behulp van de index.
Nu duurt het 1 seconde om elke query uit te voeren, in plaats van de oorspronkelijke 30-40. Dus door de voorverwerkingstijd van 2 seconden per pagina te combineren, is de totale tijd per pagina 3-4 seconden in plaats van 30-40.
Als iemand een betere oplossing heeft of als er iets flagrant mis is met deze, laat het me dan weten