Optymalizacja zapytań do bazy danych Postgis

10

Mam zestaw rastrów w formacie DTED, które ładuję do bazy danych PostGIS za pomocą narzędzia wiersza polecenia raster2pgsql.

Każdy z rastrów jest po prostu przechowywany w rzędzie i opisywany przez rid oraz wartość formatu rastrowego.

Teraz chcę utworzyć funkcję bazy danych, która pobiera długość i szerokość geograficzną punktu i zwraca wartość piksela odpowiadającą temu punktowi.

Problem, który mam, polega na tym, że zajmuje to sporo czasu (3-4 sekundy), ponieważ baza danych działa na płycie Odroid.

Wiem, że zestaw danych, który przetwarzam, jest dość duży (rastry obejmują cały obszar Wielkiej Brytanii), ale ponieważ nie jestem zbyt obeznany z PostgreSQL i PostGIS, podejrzewam, że można to zrobić szybciej.

Oto co zrobiłem do tej pory:

SELECT ST_Value(rast, ST_GeomFromText(CONCAT('POINT(', $1, ' ', $2, ')'), 4326))
FROM (
    SELECT * FROM rasters
    WHERE rast && ST_GeomFromText(CONCAT('POINT(', $1, ' ', $2, ')'), 4326)
) x;

$1i $2są odpowiednio długie i łat.

zedsdead
źródło
2
Czy pociąłeś raster na płytki podczas importowania na postgis? (parametr -t szerokość x wysokość)?
mutolisp
Tak. To trochę poprawiło wydajność. Powinienem też chyba dodać, że baza danych znajduje się na płycie Odroid, dlatego działa znacznie wolniej niż na komputerze stacjonarnym. Zastanawiałem się tylko, czy mogę w jakiś sposób zmienić podejście do przetwarzania rastrów, aby robiło to mniej niepotrzebnych obliczeń. Na przykład na początku wywoływałem funkcję ST_Value na wszystkich rastrach, a następnie szukałem wiersza, który faktycznie zawiera pewną wartość. To było najprostsze podejście, ale działało znacznie wolniej.
zedsdead
2
Używanie ST_SetSRID(ST_MakePoint($1, $2),4326)zamiast konkatek łańcuchowych może zaoszczędzić trochę czasu, jeśli jest wystarczająca liczba iteracji.
Scro
1
Wydaje się, że to niewiele pomaga, ale dziękuję. Myślałem o dodaniu kolejnej kolumny podczas tworzenia tabeli, która zawierałaby po prostu ramkę ograniczającą dla pojedynczego rastra. Być może w ten sposób można szybciej znaleźć odpowiedni raster ... Zastanawiałem się też, czy wstępne obliczenie położenia piksela w rastrze na podstawie współrzędnych narożnika i kroku pikseli w lon / lat może pomóc ... Jeśli ktoś ma jakieś przemyślenia na ten temat będę wdzięczny za dzielenie się nimi :)
zedsdead
2
Może możesz spróbować użyć „wyjaśnienia”, aby sprawdzić, gdzie jest szyjka butelki.
mutolisp

Odpowiedzi:

1

Możesz spróbować:

--calculate and store geom point just One time
WITH point_geom AS 
(
    SELECT ST_setsrid(ST_GeomFromText('POINT('|| $1 || ' '|| $2 || ')'), 4326) as geom
)
-- Your subquery is maybe useless , alias "x" isn't used
SELECT ST_Value( rast, point_geom.geom )
FROM rasters
WHERE rast && point_geom.geom;

Ale prawdziwym problemem jest pytanie o raster; sąsiadowanie zestawu danych powinno przyspieszyć zapytania. Możesz spróbować użyć PostGIS WKT Raster i postępować zgodnie z tym samouczkiem .

Mam nadzieję, że przyda się

Benno
źródło