2010-03-17 20 views
6

J'ai une grande table (> rows de 50m) qui a des données avec un ID et l'horodatage:L'accélération de requête PostgreSQL où les données sont entre deux dates

id, timestamp, data1, ..., dataN 

... avec un index à plusieurs colonnes sur (id, timestamp).

J'ai besoin d'interroger la table pour sélectionner toutes les lignes avec un certain ID où l'horodatage est entre deux dates, que je suis actuellement en train de faire en utilisant:

SELECT * FROM mytable WHERE id = x AND timestamp BETWEEN y AND z 

Cela prend actuellement plus de 2 minutes à une extrémité haute machine (2x Xeons dual-core 3Ghz avec HT, 16 Go de RAM, 2x lecteurs 1 To en RAID 0) et je voudrais vraiment accélérer.

J'ai trouvé this tip qui recommande d'utiliser un index spatial, mais l'exemple qu'il donne est pour les adresses IP. Cependant, l'augmentation de la vitesse (436s à 3s) est impressionnante. Comment puis-je l'utiliser avec les horodatages?

+0

* Définir une machine haut de gamme? Vraiment ... 50 millions de lignes est maintenant une grande table selon les normes d'aujourd'hui. * Donc, la table a ID - où est l'horodatage? * Quels indices? Un index manquant et un matériel merdique (haut de gamme + disques normaux) pourraient conduire à ces résultats. – TomTom

+0

Double Xeon Dual-cœurs 3GHz avec HT, 16 Go de RAM, etc. La table a (id, timestamp, data) avec un index multi-colonnes sur (id, timestamp). – Roger

+1

PAS haut de gamme par tous les moyens .... en particulier que vous ne dites rien sur les disques ....., qui sont la partie critique pour tout serveur de base de données. BEAUCOUP mor ethan le CPU, ou la RAM. Quelle est la disposition de votre disque? – TomTom

Répondre

0

Assurez-vous que l'index est TableID + TableTimestamp, et vous faites une requête comme:

SELECT 
    .... 
    FROM YourTable 
    WHERE TableID=..YourID.. 
     AND TableTimestamp>=..startrange.. 
     AND TableTimestamp<=..endrange.. 

si vous appliquez des fonctions à la colonne TableTimestamp de la table dans WHERE, vous ne serez pas en mesure d'utiliser complètement l'index . Si vous effectuez déjà tout cela, il est possible que votre matériel ne soit pas à la hauteur de la tâche.

si vous utilisez la version 8.2 ou ultérieure, vous devriez essayer:

WHERE (TableID, TableTimestamp) >= (..YourID.., ..startrange..) 
    and (TableID, TableTimestamp) <= (..YourID.., ..endrange..) 
6

Cette astuce ne convient que lorsque vous avez deux colonnes A et B et utiliser des requêtes telles que:

where 'a' between A and B 

C'est non:

where A between 'a' and 'b' 

en utilisant l'index sur date(column) plutôt que column pourrait accélérer un peu.

+0

Le conseil mentionne qu'il est approprié pour le temps, "Intervalle rapide (d'adresses IP ou temps) recherche avec des index spatiaux"? Merci pour l'autre indice. – Roger

+0

Il convient pour le temps. Mais cela ne convient que si votre table a des intervalles (c'est-à-dire deux colonnes) et que vous y cherchez une valeur. Pas quand vous comparez une seule colonne à un intervalle. –

+0

Ahhh, je vois. Désolé, j'avais mal compris l'application. – Roger

1

Pourriez-vous EXPLAIN la requête pour nous? Ensuite, nous savons comment la base de données exécute votre requête. Et qu'en est-il de la configuration? Quels sont les paramètres pour shared_buffers et work_mem? Et quand avez-vous (ou votre système) le dernier vide et analysez-vous? Et dernière chose, quel OS et quelle version de pgSQL utilisez-vous?

Vous pouvez créer des index merveilleux, mais sans paramètres appropriés, la base de données ne peut pas les utiliser très efficace.