Итак, я думаю, что вы использовали PgAdmin для выполнения запросов. Как ни странно, иногда, даже если есть ошибка памяти или другие ошибки времени выполнения, вы не будете уведомлены. (То же самое случилось со мной во время тестирования.) В таком случае я бы порекомендовал вам сохранить запрос в виде файла sql и запустить его с psql, чтобы убедиться, что вы получаете сообщение об ошибке:
psql -U #your_username -d #your_database -f "#your_sqlfiile.sql"
Итак, первое, что я хотел бы сделать, это настроить "work_mem" в postgresql .conf. Значение по умолчанию составляет 4 МБ, учитывая ваши спецификации, вы, вероятно, можете обрабатывать больше памяти за операцию. Я бы предложил 64 МБ для запуска в соответствии со следующей статьей:
https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server
После этого обязательно перезагрузите сервер.
Итак, Я использовал сопоставимый набор данных и получил проблемы с памятью. Настройка work_mem была первой частью. Геохеширование применимо к вашему набору данных, потому что вам нужны меньшие группы кластеров, чтобы разместить обработку в памяти, а геохешинг позволяет вам упорядочивать ваши геометрические элементы так, чтобы он уменьшал количество операций сортировки, необходимых при выполнении ST_CLUSTERINTERSECTING (я не думаю, у вас есть атрибуты для группировки, исходя из того, что я понимаю). Вот что делает следующий пример:
- Создает выходную таблицу или усекает ее, если она существует, создает последовательность или сбрасывает ее, если она существует
- "упорядоченный" Извлечение геометрии из входной таблицы и порядок по геохе sh (* геометрия должна быть в градусах, например, EPSG 4326, чтобы геоха sh)
- «сгруппировалась» Используйте последовательность, чтобы поместить данные в x количество групп , Здесь я делю на 10000, но идея в том, что ваше общее число сущностей, разделенное на x, даст вам y групп. Попробуйте сделать группы достаточно маленькими, чтобы уместиться в памяти, но достаточно большими, чтобы быть эффективными. Затем он берет каждую группу, выполняет ST_CLUSTERINTERSECTING, снимает гнездо и, наконец, ST_UNARYUNION.
- Вставляет значение с помощью ST_COLLECT и другого ST_UNARYUNION геометрии.
Вот код:
DO $$
DECLARE
input_table VARCHAR(50) := 'valid_geom';
input_geometry VARCHAR(50) := 'geom_good';
output_table VARCHAR(50) := 'unary_output';
sequence_name VARCHAR(50) := 'bseq';
BEGIN
IF NOT EXISTS (SELECT 0 FROM pg_class where relname = format('%s', output_table))
THEN
EXECUTE '
CREATE TABLE ' || quote_ident(output_table) || '(
geom geometry NOT NULL)';
ELSE
EXECUTE '
TRUNCATE TABLE ' || quote_ident(output_table);
END IF;
IF EXISTS (SELECT 0 FROM pg_class where relname = format('%s', sequence_name))
THEN
EXECUTE '
ALTER SEQUENCE ' || quote_ident(sequence_name) || ' RESTART';
ELSE
EXECUTE '
CREATE SEQUENCE ' || quote_ident(sequence_name);
END IF;
EXECUTE '
WITH ordered AS (
SELECT ' || quote_ident(input_geometry) || ' as geom
FROM ' || quote_ident(input_table) || '
ORDER BY ST_GeoHash(geom_good)
),
grouped AS (
SELECT nextval(' || quote_literal(sequence_name) || ') / 10000 AS id,
ST_UNARYUNION(unnest(ST_CLUSTERINTERSECTING(geom))) AS geom
FROM ordered
GROUP BY id
)
INSERT INTO ' || quote_ident(output_table) || '
SELECT ST_UNARYUNION(ST_COLLECT(geom)) as geom FROM grouped';
END;
$$;
Предостережения:
Измените объявленные переменные в соответствии с вашими потребностями.
Поскольку входная геометрия называется «geom» as geom
не удастся, поэтому я бы изменил SELECT ' || quote_ident(input_geometry) || ' as geom
на SELECT ' || quote_ident(input_geometry)
.
Убедитесь, что все ваши входные геометрии верны, или ST_UNARYUNION не удастся. Оформить заказ ST_ISVALID и ST_MAKEVALID.
Как уже говорилось, геохеширование требует, чтобы проекция была в градусах. Оформить заказ ST_TRANSFORM, (я преобразовал свои данные геометрии в 4326).
Дайте мне знать, если у вас есть еще вопросы.