Requête de sélection avec un décalage de la limite est trop lent

J'ai lu des ressources internet qu'une requête sera lente lorsque le décalage augmente. Mais dans mon cas, je pense que c'est trop lent. Je suis à l'aide de postgres 9.3

Voici la requête (id est clé primaire):

select * from test_table offset 3900000 limit 100;

Il me renvoie des données dans autour de 10 seconds. Et je pense que c'est trop lent. J'ai autour de 4 million enregistrements dans la table. Taille globale de la base de données est 23GB.

Configuration de la Machine:

RAM: 12 GB
CPU: 2.30 GHz
Core: 10

Quelques valeurs de postgresql.conf fichier que j'ai modifié sont comme ci-dessous. D'autres sont par défaut.

shared_buffers = 2048MB
temp_buffers = 512MB
work_mem = 1024MB
maintenance_work_mem = 256MB
dynamic_shared_memory_type = posix
default_statistics_target = 10000
autovacuum = on
enable_seqscan = off   ## its not making any effect as I can see from Analyze doing seq-scan

En dehors de ces j'ai aussi essayé en changeant les valeurs de random_page_cost = 2.0 et cpu_index_tuple_cost = 0.0005 et le résultat est le même.

Explain (analyze, buffers) résultat de la requête est comme ci-dessous:

"Limit  (cost=10000443876.02..10000443887.40 rows=100 width=1034) (actual time=12793.975..12794.292 rows=100 loops=1)"
"  Buffers: shared hit=26820 read=378984"
"  ->  Seq Scan on test_table  (cost=10000000000.00..10000467477.70 rows=4107370 width=1034) (actual time=0.008..9036.776 rows=3900100 loops=1)"
"        Buffers: shared hit=26820 read=378984"
"Planning time: 0.136 ms"
"Execution time: 12794.461 ms"

Comment les gens partout dans le monde négocie avec ce problème dans postgres? Toute autre solution sera utile pour moi.

Mise à JOUR:: Ajoutant order by id (essayé avec d'autres colonne indexée) et voici l'expliquer:

"Limit  (cost=506165.06..506178.04 rows=100 width=1034) (actual time=15691.132..15691.494 rows=100 loops=1)"
"  Buffers: shared hit=110813 read=415344"
"  ->  Index Scan using test_table_pkey on test_table  (cost=0.43..533078.74 rows=4107370 width=1034) (actual time=38.264..11535.005 rows=3900100 loops=1)"
"        Buffers: shared hit=110813 read=415344"
"Planning time: 0.219 ms"
"Execution time: 15691.660 ms"
Voulez-vous des lignes aléatoires? Car il peut y avoir des moyens plus rapides qu'en fonction d'autres conditions.
[indépendantes] work_mem = 1024MB est probablement trop élevé, default_statistics_target = 10000 est beaucoup trop élevé pour une utilisation générale. autovacuum = off n'est pas nécessaire et dangereux. Combien de temps avez-vous été courir avec autovacuum?
Je autovacuum a toujours été. J'ai mis cette off pour l'expérimentation avant l'exécution de l'expliquer.
J'ai toujours une commande par (last_update_date) à la fin de ma requête. Pour des raisons de simplicité, je l'ai enlevé qu'à partir de la question.
Retrait des choses est de ne pas ajouter plus de simplicité, mais ajouter de la confusion. S'il vous plaît montrer le réel de la requête. (en plus de la définition de la table: c'est le pk {id, update_date} ? BTW: une semblable requête s'exécute ici dans Total runtime: 12.395 ms Vous devez avoir une table différente de la structure de ce que je peux lire à partir de votre question..

OriginalL'auteur Sabuj Hassan | 2014-10-29