Voici ce que j'ai fait et j'ai réduit le temps d'exécution total d'un facteur 10.
Ce que j'ai réalisé à partir du plan d'exécution de ma requête d'origine, c'est qu'elle utilisait filesort pour trier tous les résultats et ignorer les index. C'est un peu du gaspillage.
Ma base de données de test :5 millions d'enregistrements, taille de 20 Go. structure du tableau identique à celle de la question
Au lieu d'obtenir blobCol directement dans la première requête, j'obtiens d'abord la valeur de 'name' pour le début de chaque page. Exécutez cette requête indéfiniment jusqu'à ce qu'elle renvoie 0 résultat. A chaque fois, ajoutez le résultat à une liste
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
Le numéro de page sinus n'est pas connu auparavant, commencez par la valeur 0 et continuez à incrémenter jusqu'à ce que la requête renvoie null. Vous pouvez également effectuer un comptage de sélection (*), mais cela peut prendre beaucoup de temps et n'aidera en rien à optimiser. Chaque requête prenait environ 2 secondes pour s'exécuter une fois que le nombre de pages dépassait ~60.
Pour moi, la taille de la page était de 5000, j'ai donc obtenu une liste de chaînes de 'nom' à la position 0, 5001, 10001, 15001 et ainsi de suite. Le nombre de pages s'est avéré être de 1000 et stocker une liste de 1000 résultats en mémoire n'est pas cher.
Maintenant, parcourez la liste et exécutez cette requête
SELECT blobCol
FROM my_table
where name >= <pageHeader>
and name < <nextPageHeader>
and city="<any string>"
and id= 1
Cela s'exécutera N fois, où N =taille de la liste obtenue précédemment. Étant donné que 'nom' est la colonne de la clé primaire et que 'ville' est également indexée, EXPLAIN montre que ce calcul est effectué en mémoire à l'aide de l'index.
Désormais, chaque requête prend 1 seconde pour s'exécuter, au lieu des 30-40 d'origine. Ainsi, en combinant le temps de prétraitement de 2 secondes par page, le temps total par page est de 3-4 secondes au lieu de 30-40.
Si quelqu'un a une meilleure solution ou s'il y a quelque chose qui ne va pas avec celle-ci, merci de me le faire savoir