Обновление таблицы с 2 миллионами строк с помощью Postgres / PostGIS - PullRequest
0 голосов
/ 09 апреля 2020

У меня есть две таблицы:

  • properties (geo_point POINT, locality_id INTEGER, окрестность_id INTEGER, идентификатор UUID)
  • places_temp (идентификатор INTEGER, poly GEOMETRY, placetype ТЕКСТ)

Примечание: все столбцы в places_temp проиндексированы.

properties имеет ~ 2 миллиона строк, и я хотел бы:

  • обновить locality_id и neighborhood_id для каждой строки в properties с помощью id из places_temp, где properties.geo_point содержится в многоугольнике в places_temp.poly

Что бы я ни делал кажется, он просто зависает в течение нескольких часов, в течение которых я не знаю, работает ли он, потеряно ли соединение, и т. д. c.

Есть какие-нибудь мысли о том, как сделать это качественно?

Мой запрос:

  -- drop indexes on locality_id and neighborhood_id to speed up update
  DROP INDEX IF EXISTS idx_properties_locality_id;
  DROP INDEX IF EXISTS idx_properties_neighborhood_id;
  -- for each property find the locality and neighborhood
  UPDATE
    properties
  SET
    locality_id = (
      SELECT
        id
      FROM
        places_temp
      WHERE
        placetype = 'locality'
        -- check if geo_point is contained by polygon. geo_point is stored as SRID 26910 so must be
        -- transformed first
        AND st_intersects (st_transform (geo_point, 4326), poly)
      LIMIT 1),
  neighborhood_id = (
    SELECT
      id
    FROM
      places_temp
    WHERE
      placetype = 'neighbourhood'
      -- check if geo_point is contained by polygon. geo_point is stored as SRID 26910 so must be
      -- transformed first
      AND st_intersects (st_transform (geo_point, 4326), poly)
    LIMIT 1);
  -- Add indexes back after update
  CREATE INDEX IF NOT EXISTS idx_properties_locality_id ON properties (locality_id);
  CREATE INDEX IF NOT EXISTS idx_properties_neighborhood_id ON properties (neighborhood_id);

Ответы [ 2 ]

0 голосов
/ 09 апреля 2020

Попробуйте это

        UPDATE
      properties
   SET
    locality_id =t.id, neighbourhood_id
    =t.id
    From(
    SELECT
    id
    FROM
    places_temp
  WHERE
    placetype in ('locality',  
   'neighbourhood') 
    AND st_intersects (st_transform 
   (geo_point, 4326), poly)
  LIMIT 1)) t
0 голосов
/ 09 апреля 2020
CREATE INDEX properties_point_idx ON properties USING gist (geo_point);
CREATE INDEX places_temp_poly_idx ON places_temp USING gist (poly);

UPDATE properties p
SET locality_id = x.id
FROM ( SELECT *
        , row_number() OVER () rn
        FROM places_temp t 
        WHERE t.placetype = 'locality'
        AND st_intersects (st_transform (p.geo_point, 4326), t.poly)
        )x
WHERE x.rn = 1
      ;

И аналогично для другого поля (вы можете объединить их в один запрос)

...