L'amélioration de la vitesse de requête: SELECT simple dans les grandes postgres table

Je vais avoir des ennuis au sujet de la vitesse dans une requête SELECT sur une base de données Postgres.

J'ai un tableau avec deux colonnes de type entier clés: (int1,int2)
Ce tableau a environ 70 millions de lignes.

J'ai besoin de faire deux sortes de simples requêtes SELECT dans cet environnement:

SELECT * FROM table WHERE int1=X;
SELECT * FROM table WHERE int2=X;

Ces deux sélectionne retourne près de 10 000 lignes de chacun de ces 70 millions de dollars. Pour que cela fonctionne aussi vite que possible, je pensais que sur l'aide de deux HASH index, un pour chaque colonne. Malheureusement, les résultats ne sont pas bons:

                                                               QUERY PLAN                                                               
----------------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on lec_sim  (cost=232.21..25054.38 rows=6565 width=36) (actual time=14.759..23339.545 rows=7871 loops=1)
   Recheck Cond: (lec2_id = 11782)
   ->  Bitmap Index Scan on lec_sim_lec2_hash_ind  (cost=0.00..230.56 rows=6565 width=0) (actual time=13.495..13.495 rows=7871 loops=1)
         Index Cond: (lec2_id = 11782)
 Total runtime: 23342.534 ms
(5 rows)

C'est un explain analyze exemple de l'une de ces requêtes. Il est à prendre autour de 23 secondes. Mes attentes sont pour obtenir cette information en moins d'une seconde.

Ce sont certains paramètres de la postgres db config:

work_mem = 128MB
shared_buffers = 2GB
maintenance_work_mem = 512MB
fsync = off
synchronous_commit = off
effective_cache_size = 4GB

Toute aide, des commentaires ou de la pensée, ce serait vraiment apprécié.

Vous en remercie d'avance.

  • Dans le cadre de votre temps total de combien cela est d'envoyer les données en arrière pour vous? Êtes-vous d'exécuter la requête sur la même machine que la base de données ou allez-vous sur le fil?
  • le temps indiqué dans l'expliquer de sortie est le temps pour la préparation de la requête sur le serveur (sans côté client allers-retours)
  • Hash index ne sont pas très efficaces dans PostgreSQL. Avez-vous essayé ordinaire B-Arbre d'index? Avez-vous un index pour chaque colonne, ou un indice combiné sur deux? Pour lequel des deux états est la publication du plan d'exécution?
  • JustBob, a_horse_with_no_name répondu mieux que je le ferais. Je crois que pour moi, pour recevoir les données sont assez instantanée puisqu'il y a 2 flotteurs seulement en tant que données.
  • a_horse_with_no_name, au début, ils sont le B-Arbre d'index, et, comme ils étaient en marche lente, j'ai changé d'index de hachage. Il y a 3 indices de réalité: la principale (int1, int2) comme B-Arbre, puis un index de hachage pour chaque colonne: hash (int1), hash (int2). Merci.
  • L'index de recherche ici a été très rapide tout le temps a été consacré à la récupération des lignes réelles. 23 secondes / 7871 rows = 2.9 millisecondes par ligne, ce qui est raisonnable pour la récupération des données qui sont dispersés à travers le sous-système de disque. Cherche sont lents; vous pouvez a) s'adapter à votre jeu de données dans la mémoire RAM, b) acheter des disques Ssd, ou c) d'organiser vos données à l'avance pour minimiser les cherche.
  • Merci beaucoup, je ne savais pas que c'était le moment d'être passé sur la recherche de données au lieu de chercher à l'index. Donc, oubliez sur les indices liés au questionnement, j'aimerais voir comment ai-je pu organiser ces données pour prendre plus rapidement de la HD. Peut-être que je pourrais commander les lignes (int1) dans une table, et une copie de la table de l'ordre de (int2), et d'effectuer la requête SELECT sur ces deux tableaux en fonction de l'index de la clé, je suis à la recherche d'. Toutes les meilleures idées ici? Serait-il travailler plus vite? Je vous remercie beaucoup.
  • Deux tables est une option, surtout si vous CLUSTER deux d'entre eux. Cependant, PostgreSQL 9.2 ajoute une fonctionnalité appelée index ne scanne qui est particulièrement utile, ici, de faire un btree indice au-dessus de toutes les colonnes d'intérêt (qui PostgreSQL maintient automatiquement dans l'ordre), et la requête peut (probablement) être résolues en utilisant uniquement l'index, sans aucun supplément de cherche.

InformationsquelleAutor alexdemartos | 2012-11-05