Question

J'ai l'impression d'avoir très lente des requêtes sur un support de taille RDS boîte (db.m3.moyenne, 3,7 go de ram).

C'est à travers une table de 4,152,928 lignes..

select sum(some_field) c
from pages
where pages.some_id=123
and pages.first_action_at > '2014-01-01 00:00:00 +1000'

La durée totale d'utilisation:45031 mme.
Localement, j'ai environ 1,1 million de lignes, et la même requête prend environ 450 ms..

Voici le plan de requête, de l'expliquer:

Aggregate  (cost=475640.59..475640.60 rows=1 width=4)
   ->  Seq Scan on pages  (cost=0.00..475266.07 rows=149809 width=4)
         Filter: ((first_action_at > '2014-01-01 00:00:00'::timestamp without time zone) 
                AND (some_id = 447))

Voici la réponse de l'expliquer, analyser:

 Aggregate  (cost=475641.74..475641.76 rows=1 width=4) (actual time=42419.717..42419.718 rows=1 loops=1)
   ->  Seq Scan on pages  (cost=0.00..475267.22 rows=149810 width=4) (actual time=0.013..42265.908 rows=141559 loops=1)
    Filter: ((first_action_at > '2014-01-01 00:00:00'::timestamp without time zone) AND (some_id = 447))
    Rows Removed by Filter: 4011369

La durée totale d'utilisation:42419.772 ms

Pour référence, 141559 lignes font partie de la somme().

L'actuel indices que j'ai sont:

:some_id
:some_id, :first_action_at

work_mem était précédemment fixé à 1 mo RDS (par défaut).Je viens de changer cette à 18 mo.

Edit:Semble être résolu en faisant monter work_mem ainsi que d'ajouter le deuxième indice ci-dessus, la vitesse est désormais autour de 800 ms.

Était-ce utile?

La solution

Correspondant de l'indice de

Après re-lecture de votre question, j'ai réalisé que vous ne sont pas en cours d'exécution Amazon Redshift, mais Amazon RDS, qui semble être en cours d'exécution, sans tache Postgres, au moins selon la documentation:

Amazon RDS prend en charge les instances DB exécution de plusieurs versions de PostgreSQL.Actuellement, nous utilisons les versions de PostgreSQL 9.3.1, 9.3.2 et 9.3.3.

Cela signifierait que vous avez index-analyse uniquement à votre disposition.Si vous répondez à certaines conditions préalables (en gros si vacuum peut suivre les opérations d'écriture) et si some_field n'est pas mis à jour souvent et de taille raisonnable (ce qui semble être le cas pour une colonne numérique), le parfait index de l'inclure some_field en dernière position (comme @zerkms d'abord mentionné):

CREATE INDEX ON pages(some_id, first_action_at, some_field);

Notez que some_id devrait venir avant first_action_at, car il est généralement plus efficace pour avoir des colonnes avec l'égalité des contrôles de premier et de plages plus tard.Détails:
Index multicolonne et de la performance

Si vous ne voyez pas "index-only scan" dans EXPLAIN ANALYZE, la dernière colonne est tout simplement de lest et laissées à l'écart:

CREATE INDEX ON pages(some_id, first_action_at);

(Comme vous l'avez maintenant, en fonction de votre question de mise à jour.)

De toute façon, un autre indice sur (some_id) seulement n'offre que très peu au cours de cette index multicolonne:
Est un indice composite aussi bien pour les requêtes sur le premier champ?

Configuration du serveur

Tous les conseils habituels pour les requêtes lentes et la bonne configuration du serveur s'applique et un work_mem réglage de 1 MO est beaucoup trop faible pour un DB avec des millions de lignes.Mais ce paramètre ne doit pas être cruciale pour cette question particulière, depuis work_mem est (par la documentation):

mémoire à utiliser en interne les opérations de tri et de tables de hachage.

Ne s'applique pas ici.

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top