J'ai deux tables, left2
et right2
. Les deux tables seront grandes (1 à 10 millions de lignes).
CREATE TABLE left2(id INTEGER, t1 INTEGER, d INTEGER);
ALTER TABLE left2 ADD PRIMARY KEY (id,t1);
CREATE TABLE right2( t1 INTEGER, d INTEGER, arr INTEGER[] );
ALTER TABLE right2 ADD PRIMARY KEY(t1,d);
Je vais effectuer ce type de requête:
SELECT l.d + r.d,
UNIQ(SORT((array_agg_mult(r.arr)))
FROM left2 l,
right2 r
WHERE l.t1 = r.t1
GROUP BY l.d + r.d
ORDER BY l.d + r.d;
Où pour l'agrégation de tableaux, j'utilise la fonction:
CREATE AGGREGATE array_agg_mult(anyarray) (
SFUNC=array_cat,
STYPE=anyarray,
INITCOND='{}');
Après avoir concaténé les tableaux, j'utilise la UNIQ
fonction du intarray
module. Existe-t-il un moyen plus efficace de procéder? Existe-t-il un index sur le arr
terrain pour accélérer la fusion (avec suppression des doublons)? La fonction d'agrégation peut-elle supprimer directement les doublons? Les tableaux originaux peuvent être considérés comme triés (et ils sont uniques) si cela aide.
Le SQL Fiddle est ici :
postgresql
postgresql-9.3
aggregate
array
Alexandros
la source
la source
right2.arr
être NULL comme le suggère votre schéma de démonstration? Avez-vous besoin de tableaux triés en conséquence?Réponses:
Des résultats corrects?
Tout d'abord: l'exactitude. Vous souhaitez produire un tableau d'éléments uniques? Votre requête actuelle ne fait pas cela. La fonction
uniq()
du module intarray ne promet que:Comme indiqué dans le manuel , vous aurez besoin de:
Vous donne également des tableaux triés - en supposant que vous le vouliez, vous n'avez pas clarifié.
Je vois que vous avez
sort()
dans votre violon , donc ce n'est peut-être qu'une faute de frappe dans votre question.Postgres 9.5
Quoi qu'il en soit, vous allez adorer le nouveau Postgres 9.5 (actuellement en version bêta). Il offre les capacités prêtes
array_agg_mult()
à l'emploi et beaucoup plus rapides:Il y a également eu d'autres améliorations de performances pour la gestion des baies.
Requete
L'objectif principal de
array_agg_mult()
est d'agréger des tableaux multidimensionnels, mais vous ne produisez de toute façon que des tableaux unidimensionnels. Je voudrais donc au moins essayer cette requête alternative:Ce qui répond également à votre question:
Oui, c'est possible, avec
DISTINCT
. Mais ce n'est pas plus rapide queuniq()
pour les tableaux entiers, qui a été optimisé pour les tableaux entiers, tandis qu'ilDISTINCT
est générique pour tous les types de données éligibles.Ne nécessite pas le
intarray
module. Cependant , le résultat n'est pas nécessairement trié. Postgres utilise différents algorithmes pourDISTINCT
(IIRC), les grands ensembles sont généralement hachés, puis le résultat n'est pas trié sauf si vous ajoutez explicitementORDER BY
. Si vous avez besoin de tableaux triés, vous pouvez ajouterORDER BY
directement à la fonction d'agrégation:Mais c'est généralement plus lent que de fournir des données pré-triées
array_agg()
(un grand tri par rapport à de nombreux petits tri). Je trierais donc dans une sous-requête, puis j'agrégerais:C'était la variante la plus rapide de mon test superficiel sur Postgres 9.4.
SQL Fiddle basé sur celui que vous avez fourni.
Indice
Je ne vois pas beaucoup de potentiel pour un indice ici. La seule option serait:
Cela n'a de sens que si vous obtenez des analyses d'index uniquement - ce qui se produira si la table sous-jacente
right2
est nettement plus large que ces deux colonnes et que votre configuration est qualifiée pour les analyses d'index uniquement. Détails dans le wiki Postgres.la source
Je suis vraiment déçu, c'est une chose facile à faire dans Microsoft Access. Vous pouvez créer une requête "supprimer les doublons", puis regarder le SQL pour voir comment il le fait. Je vais devoir allumer une machine Windows pour regarder. Ils varient, l'assistant de requête le fait.
Une chose qui fonctionne, je pense, est de charger toutes vos données dans une table, puis de faire SELECT DISTINCT dans une nouvelle table. Vous pouvez également coller une clause de commande par ordre pendant que vous y êtes. Je l'ai fait il y a un an, ça doit être ça.
Je combine 2 années de données de température, le capteur envoie chaque minute 2 copies du même point de données comme sauvegarde redondante. Parfois, on se fait saccager, mais je veux seulement en garder un. J'ai également des chevauchements entre les fichiers.
Si les données sont exactement au même format sur l'ensemble du cycle, sur une machine Unix, vous pouvez faire quelque chose comme
Mais uniq compare les lignes comme des chaînes et, par exemple, 18.7000 n'est pas identique à 18.7. J'ai changé de logiciel pendant 2 ans donc j'ai les deux formats.
la source