Ich habe zwei Tische left2
und right2
. Beide Tabellen sind groß (1-10 Millionen Zeilen).
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);
Ich werde diese Art von Abfrage durchführen:
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;
Wo ich für die Aggregation von Arrays die Funktion benutze:
CREATE AGGREGATE array_agg_mult(anyarray) (
SFUNC=array_cat,
STYPE=anyarray,
INITCOND='{}');
Nach dem Verketten der Arrays verwende ich die UNIQ
Funktion des intarray
Moduls. Gibt es eine effizientere Möglichkeit, dies zu tun? Gibt es einen Index für das arr
Feld, um das Zusammenführen zu beschleunigen (mit dem Entfernen von Duplikaten)? Kann die Aggregatfunktion Duplikate direkt entfernen? Original-Arrays können als sortiert betrachtet werden (und sie sind eindeutig), wenn dies hilfreich ist.
Die SQL-Geige ist hier :
postgresql
postgresql-9.3
aggregate
array
Alexandros
quelle
quelle
right2.arr
NULL sein, wie es Ihr Demo-Schema vorschlägt? Benötigen Sie als Ergebnis sortierte Arrays?Antworten:
Richtige Ergebnisse?
Zunächst einmal: Korrektheit. Sie möchten eine Reihe einzigartiger Elemente erstellen? Ihre aktuelle Abfrage macht das nicht. Die Funktion
uniq()
des Intarray- Moduls verspricht nur:Wie im Handbuch beschrieben , benötigen Sie:
Gibt Ihnen auch sortierte Arrays - vorausgesetzt, Sie möchten das, haben Sie nicht geklärt.
Ich sehe, Sie haben
sort()
in Ihrer Geige , also kann dies nur ein Tippfehler in Ihrer Frage sein.Postgres 9.5
In jedem Fall werden Sie den neuen Postgres 9.5 (derzeit Beta) lieben . Es bietet die Funktionen von
array_agg_mult()
sofort einsatzbereit und viel schneller:Es gab auch andere Leistungsverbesserungen für die Array-Handhabung.
Abfrage
Der Hauptzweck von
array_agg_mult()
besteht darin, mehrdimensionale Arrays zu aggregieren, aber Sie erzeugen sowieso nur eindimensionale Arrays. Also würde ich zumindest diese alternative Abfrage versuchen:Welches auch Ihre Frage anspricht:
Ja, das kann es mit
DISTINCT
. Dies ist jedoch nicht schneller alsuniq()
bei Integer-Arrays, die für Integer-Arrays optimiert wurden, während sieDISTINCT
für alle qualifizierenden Datentypen generisch sind.Benötigt das
intarray
Modul nicht. Das Ergebnis ist jedoch nicht unbedingt sortiert. Postgres verwendet unterschiedliche Algorithmen fürDISTINCT
(IIRC). Große Mengen werden normalerweise gehasht. Das Ergebnis wird nur sortiert, wenn Sie explizit hinzufügenORDER BY
. Wenn Sie sortierten Arrays benötigen, Sie könnten hinzufügen ,ORDER BY
direkt auf die Aggregatfunktion:Dies ist jedoch in der Regel langsamer als das Zuführen vorsortierter Daten
array_agg()
(eine große Sortierung gegenüber vielen kleinen Sortierungen). Also würde ich in einer Unterabfrage sortieren und dann aggregieren:Dies war die schnellste Variante in meinem flüchtigen Test auf Postgres 9.4.
SQL Fiddle basierend auf dem von Ihnen angegebenen.
Index
Ich sehe hier nicht viel Potenzial für einen Index. Die einzige Option wäre:
Dies ist nur dann sinnvoll, wenn Sie nur Index-Scans erhalten. Dies ist der Fall, wenn die zugrunde liegende Tabelle
right2
wesentlich breiter als nur diese beiden Spalten ist und Ihr Setup für Nur-Index-Scans qualifiziert ist. Details im Postgres Wiki.quelle
Ich bin wirklich enttäuscht, dies ist in Microsoft Access ganz einfach. Sie können eine Abfrage zum Entfernen von Duplikaten erstellen und dann in SQL nachsehen, wie dies funktioniert. Ich muss einen Windows-Computer starten, um zu schauen. Sie variieren, der Abfrage-Assistent macht es.
Eine Sache, die meiner Meinung nach funktioniert, ist, alle Ihre Daten in eine Tabelle zu laden und dann SELECT DISTINCT in eine neue Tabelle auszuführen. Sie können auch eine Order-by-Klausel einhalten, während Sie gerade dabei sind. Ich habe es vor einem Jahr irgendwie gemacht, das muss es sein.
Ich kombiniere Temperaturdaten im Wert von 2 Jahren. Der Sensor sendet jede Minute 2 Kopien desselben Datenpunkts als redundanten Schutz. Manchmal wird man verwüstet, aber ich möchte nur einen behalten. Ich habe auch Überlappungen zwischen Dateien.
Wenn die Daten während des gesamten Laufs genau das gleiche Format haben, können Sie auf einem Unix-Computer so etwas tun
Aber uniq vergleicht Zeilen als Zeichenfolgen und zum Beispiel ist 18.7000 nicht dasselbe wie 18.7. Ich habe meine Software in den 2 Jahren geändert, sodass ich beide Formate habe.
quelle