Mam dwa stoły left2
i right2
. Obie tabele będą duże (1-10 mln wierszy).
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);
Wykonam ten typ zapytania:
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;
Gdzie do agregacji tablic używam funkcji:
CREATE AGGREGATE array_agg_mult(anyarray) (
SFUNC=array_cat,
STYPE=anyarray,
INITCOND='{}');
Po połączeniu tablic korzystam z UNIQ
funkcji intarray
modułu. Czy istnieje bardziej skuteczny sposób to zrobić? Czy w arr
polu jest jakiś indeks przyspieszający scalanie (z usuwaniem duplikatów)? Czy funkcja agregująca może bezpośrednio usuwać duplikaty? Oryginalne tablice można uznać za posortowane (i są unikalne), jeśli to pomaga.
Fiddle SQL jest tutaj :
postgresql
postgresql-9.3
aggregate
array
Alexandros
źródło
źródło
right2.arr
mieć wartość NULL, jak sugeruje schemat demonstracyjny? Czy potrzebujesz wynikowo posortowanych tablic?Odpowiedzi:
Prawidłowe wyniki?
Po pierwsze: poprawność. Chcesz stworzyć szereg unikalnych elementów? Twoje obecne zapytanie tego nie robi. Funkcja
uniq()
z modułu intarray obiecuje tylko:Jak nakazuje to instrukcja , musisz:
Daje także posortowane tablice - zakładając, że tego chcesz, nie wyjaśniłeś.
Widzę, że masz
sort()
skrzypce , więc może to być literówka w twoim pytaniu.Postgres 9.5
Tak czy inaczej, spodoba ci się nowy Postgres 9.5 (obecnie beta). Zapewnia możliwości
array_agg_mult()
gotowego i znacznie szybszego:Wprowadzono również inne ulepszenia wydajności w zakresie obsługi tablicy.
Pytanie
Głównym celem
array_agg_mult()
jest agregacja tablic wielowymiarowych, ale i tak powstają tablice 1-wymiarowe. Chciałbym więc przynajmniej spróbować tego alternatywnego zapytania:Co również dotyczy twojego pytania:
Tak, może
DISTINCT
. Nie jest to jednak szybsze niż wuniq()
przypadku tablic całkowitoliczbowych, które zostały zoptymalizowane dla tablic całkowitoliczbowych, podczas gdyDISTINCT
jest ogólne dla wszystkich kwalifikujących się typów danych.Nie wymaga
intarray
modułu. Jednak wynik niekoniecznie jest posortowany. Postgres używa różnych algorytmów dlaDISTINCT
(IIRC), duże zestawy są zwykle mieszane, a następnie wynik nie jest sortowany, chyba że dodasz wyraźneORDER BY
. Jeśli potrzebujesz posortowane tablice, to mógłby dodaćORDER BY
do łącznej funkcji bezpośrednio:Ale zwykle jest to wolniejsze niż podawanie wstępnie posortowanych danych
array_agg()
(jeden duży sort w porównaniu z wieloma małymi). Więc posortowałbym podzapytanie, a następnie agregował:To był najszybszy wariant w moim pobieżnym teście na Postgres 9.4.
Fiddle SQL oparty na tym, który podałeś.
Indeks
Nie widzę tutaj dużego potencjału dla żadnego indeksu. Jedyną opcją byłoby:
Ma to sens tylko wtedy, gdy uzyskuje się z tego skany tylko indeksowe - co stanie się, jeśli podstawowa tabela
right2
jest znacznie szersza niż tylko te dwie kolumny, a twoja konfiguracja kwalifikuje się do skanów tylko indeksowych. Szczegóły na Wiki Postgres.źródło
Jestem naprawdę rozczarowany, jest to łatwa rzecz w Microsoft Access. Możesz utworzyć zapytanie „usuń duplikaty”, a następnie spójrz na SQL, aby zobaczyć, jak to robi. Będę musiał odpalić komputer z systemem Windows, aby sprawdzić. Różnią się, kreator zapytań to robi.
Myślę, że jedną rzeczą jest załadowanie wszystkich danych do jednej tabeli, a następnie WYBIERZ ODRÓŻNIENIE do nowej tabeli. Możesz również trzymać się kolejności według klauzuli, gdy jesteś przy niej. Zrobiłem to jakoś rok temu, to musi być to.
Łączę dane temperaturowe z 2 lat, czujnik wysyła 2 kopie tego samego punktu danych co minutę jako rezerwowe zabezpieczenie. Czasami ktoś zostaje zniszczony, ale ja chcę go tylko zatrzymać. Mam także nakładki między plikami.
Jeśli dane mają dokładnie ten sam format przez cały czas, na maszynie uniksowej możesz zrobić coś takiego
Ale uniq porównuje linie jako łańcuchy i na przykład 18,7000 to nie to samo co 18,7. Zmieniłem oprogramowanie w ciągu 2 lat, więc mam oba formaty.
źródło