2012-07-01 12 views
5

Mam dwie tabele, które chciałbym przeciąć. Pierwsza tabela przedstawia około 50 milionów punktów, a druga to wielobokowa warstwa wszystkich krajów na świecie. Chcę uzyskać wszystkie punkty, które przecinają się z tym wielokątem.Kwerenda przestrzenna PostgreSQL zbyt wolna

SELECT d.id, d.geom 
FROM export d, world_boundaries b 
WHERE (b.cntry_name = 'UK') 
    AND d.date_inserted >= '2012-06-01' 
    AND d.geom && b.wkb_geometry 
    AND intersects(d.geom, b.wkb_geometry); 

To zapytanie jest bardzo proste, ale trwa dłużej niż 4 godziny. Mam indeksy GIST zbudowane na kolumnie geometrii dla każdej tabeli i mają ANULOWANĄ PRÓŻNICĘ obie te wartości. Nadal nie wzrost wydajności. Używam CENTOS 6 z Postgres 8.4 i PostGIS 1.5. Czy ktoś może rzucić trochę światła na to, jak przyspieszyć działania? Bardzo szybko uzyskuję wyniki, gdy OGRANICZAM zapytanie do 1000 do 10000 rekordów. Kiedy próbuję pobrać cały zestaw wyników, przeciąga. Myśli?

AKTUALIZACJA: Teraz widzę, że muszę zawęzić moje zapytanie jako pierwszy krok w tym procesie. Dostaję kopertę w następujący sposób: Jaki jest najskuteczniejszy sposób włączenia/wykonania tego w ramach całego zapytania?

+1

Każda z ostatnich wersji poprawiła indeksy GiST i GIN. Możesz rozważyć aktualizację do nowej wersji głównej. Być może warto wypróbować swój problem w wersji 9.2 beta, ponieważ zawiera on SP-GiST. http://www.postgresql.org/docs/9.2/static/spgist-intro.html – kgrittn

Odpowiedz

1

Spróbuj uruchomić go za pomocą EXPLAIN (i LIMIT), aby sprawdzić, czy indeksy są w ogóle używane.

Ponieważ sprawdzanie prawdziwego skrzyżowania jest najwolniejszą operacją, może być pomocne uruchomienie go pod ST_Collect podzapytania (wszystko poza sprawdzeniem ST_Intersects). W ten sposób będzie tylko jedno połączenie i jeśli konstrukcja multigeometry będzie wystarczająco szybka, wynik netto może być lepszy.

Edit1: Cóż, okazuje się, że nie jest tak optymalne, ponieważ chyba że zmusi współrzędne do 3d (trzymać również identyfikator), dodatkowy odnośników jest potrzebne, aby uzyskać identyfikator Geometria:

SELECT d.id, d.geom 
FROM 
(
    SELECT * 
    FROM 
    ( 
     SELECT ST_Collect(d.geom) 
     FROM export d, world_boundaries b 
     WHERE (b.cntry_name = 'UK') 
     AND d.date_inserted >= '2012-06-01' 
     AND d.geom && b.wkb_geometry 
    ) as c, world_boundaries b 
    WHERE (b.cntry_name = 'UK') 
    AND ST_Intersection(c.geom, b.wkb_geometry); 
) as e, export d 
WHERE (ST_Dump(e.geom)).geom = d.geom 
+2

Nie oczekuj, że plan wygenerowany z 'LIMIT' będzie koniecznie przypominał plan bez' LIMIT'. To * może * być takie samo, ale może być zupełnie inaczej, ponieważ planista będzie szukał najtańszego planu, aby zwrócić żądaną liczbę wierszy, a najtańszy plan do zwrócenia wszystkich wierszy. Te często się różnią. – kgrittn

+0

Czy istnieje szansa na podanie przykładowego podkwerendy ST_Collect(), tak jak w powyższej instrukcji SQL? – aeupinhere

+0

@kgrittn Oczywiście, ale bardzo wątpię, że taniej byłoby nie używać tam indeksu, więc powinno to być w porządku jako diagnoza dla tego, co powiedziałem. – lynxlynxlynx