Как ускорить запросы к растровым базам данных?

16

У меня есть растровая база данных в postgresql / postgis с этими столбцами:

(ID, раст, data_of_data) .

«Раст» - это столбец с растровыми файлами в формате WKT. Пример запроса для поиска значения DN точки в системе WGS84 (30.424, -1.66) и для 2002-01-09 выглядит следующим образом:

SELECT 
     st_value(rast,(st_GeomFromText('POINT(30.424 -1.66)', 4326))) as val
FROM 
     my_table
WHERE
     date_of_data='2002-01-09'

Есть ли способ (например, пространственный индекс) для ускорения таких запросов?

f.ashouri
источник
Возможно, вы могли бы помочь нам, предоставив более подробную информацию: Сколько записей в my_table? Насколько велики данные в растровом столбце? Сколько разных дат у вас в date_of_data?
dwurf
Добавьте к этому: что такое SRID столбца rast?
dwurf

Ответы:

12

Это захватывающий вопрос! Насколько большой растр вы хотите запросить? WKTRaster хранится в базе данных как BLOB . Чтобы найти значение в конкретной точке, из известных (x_0, y_0) угловых координат строки / столбцов индексы (i, j) вычисляются с использованием (dx, dy) шагов и поворота. С известным (i, j), функция ST_Value () может получить доступ к фактическим данным с правильным байтовым смещением.

Это означает, что при ответе на запрос к точке БД должна в среднем прочитать хотя бы половину большого двоичного объекта данных (в зависимости от реализации она может фактически всегда считывать все данные). Поэтому я бы предположил, что производительность WKTRaster страдает, когда большие двоичные объекты данных становятся слишком большими. Черепица набора данных должна ускорить запросы. Посмотрите, как обрабатываются данные SRTM (поступающие в виде фрагментов размером 6000x6000 пикселей) в этом руководстве . Они на самом деле разбивают данные на очень маленькие 50x50 пикселей, что является явным намеком на то, что мои догадки могут быть не слишком далеки от истины.

Пространственная индексация растровых данных, вероятно, будет просто индексировать ограничивающий прямоугольник, что не поможет в вашей проблеме.

bhell
источник
1
Плитка, кажется, способ пойти - см. Эту ссылку . Вам также необходимо добавить индекс, подобный следующему: CREATE INDEX srtm_tiled_rast_gist_idx ON srtm_tiled USING GIST (ST_ConvexHull(rast));( источник )
dwurf
4

Два аспекта, которые я обнаружил, ускорили мои расчеты растра PostGIS: использование целочисленных значений в растре и использование многоканальных растров, где это возможно. В этом случае, может ли значение DN быть сохранено как целые числа, если это еще не сделано?

Другая мысль (и я не уверен, что это уместно здесь) заключается в использовании многоканальных растров. Например, если вы просматриваете ежемесячные фрагменты данных, каждый месяц может быть растровым слоем. Затем вы можете получить несколько значений точки на разных временных срезах, запросив многоуровневый растр. Я обнаружил, что такой подход намного быстрее, чем запросы к отдельным растрам.

Наконец, когда вы загружаете свои данные, появляется -tфлаг для TILE_SIZE . Вы можете выяснить, подходит ли используемый вами размер плитки для вашего запроса.

djq
источник
Многополосные растры, скорее всего, помогут, если вам нужно запрашивать одно и то же значение пикселя в течение нескольких месяцев в одно и то же время (например, для анализа вашего временного ряда). Запрос в вопросе получает только одну конкретную дату. Если бы дата содержалась в одной полосе, СУБД также должна была бы прочитать все остальные полосы, даже если они не представляют интереса для ответа на запрос. Это, вероятно, ухудшит производительность.
Bhell
Я согласен - возможно, я не подчеркивал, что это полезно, только если необходимо несколько значений одновременно; Я уточню это.
DJQ
3

В зависимости от распределения ваших данных, вы можете получить очень хорошие ускорения, просто проиндексировав date_of_dataстолбец.

Вы можете использовать синтаксис EXPLAIN ANALYZE, чтобы выяснить, используются ли ваши индексы или нет.

dwurf
источник
что за индекс? Не могли бы Вы уточнить?
f.ashouri
Просто стандартный индекс btree create index tbl_name_date_idx on tbl_name (date_of_data). Если у вас много разных дат, это резко сократит объем данных, которые должен обрабатывать PostGIS.
dwurf
Спасибо, но это не сработало для моего запроса.
f.ashouri
Как это не сработало? Нет заметного прироста производительности или других проблем? Если у вас есть столбец таблицы, который регулярно появляется в WHEREпредложении, вы всегда должны учитывать его индексацию. Это поможет не только в этом случае, если у вас много разных дат (т. Е. Домен с большим значением), но также если у вас есть большое количество записей в таблице.
Bhell
Использует ли запрос индекс? Вы можете вставить вывод explain analyze SELECT st_value(rast,(st_GeomFromText('POINT(30.424 -1.66)', 4326))) as val from my_table where date_of_data='2002-01-09'?
dwurf