Мне нужно было подобрать сценарий, в котором его оставил парень до меня, и мне нужна помощь.
Итак, у меня есть несколько таблиц с почти миллионами строк в каждой, и мне нужно сделать INSERT втаблица результатов с предыдущим SELECT из этих таблиц.Дело в том, что мне нужен этот SELECT, чтобы получить расстояние между двумя таблицами, но меня интересует только вставка таблицы с наименьшим расстоянием (ближайший сосед от таблицы к другой. Следующий запрос все делает правильно, но он вставляет огромныйколичество дубликатов от каждого объекта из таблицы P до каждого объекта в таблице V на заданном расстоянии. Чтобы исправить это, у меня есть другой запрос, который удаляет для каждого идентификатора из таблицы P все дубликаты, оставляя только один с самым коротким расстоянием.
Это работает быстро для небольших примеров, но когда я добираюсь до настоящих больших таблиц, на диске заканчивается свободное место из-за всех создаваемых им дубликатов, прежде чем он сможет добраться до запроса, удаляющего дубликаты.
INSERT INTO result(id_state, name_m, id_m, type_l, \
name_l, id_l, cab_l, name_c, \
type_d, di, \
numext, port, id5, gid, pro, \
Y, X, geom, distance,cat_v, type_v, vi, id_v) \
(select '{0}'m.name, l.cv, l.type,l.name, l.loc, l.cab, \
c.name,d.type, s.distr, \
p.numext, p.portal, p.id5, p.gid, p.pro, \
ST_Y(p.geom), ST_X(p.geom) ,p.geom, ST_DISTANCE(p.geom,v.geom), v.cat, v.type, v.name, v.id, \
FROM m, l, c, v, \
d, s \
WHERE p.state = '{0}'\
AND left(m.cm) = '{0}'\
AND p.id5 = {1}\
AND ST_INTERSECTS(p.geom, m.geom)\
AND ST_INTERSECTS(p.geom, l.geom)\
AND ST_INTERSECTS(p.geom, d.geom)\
AND ST_INTERSECTS(p.geom, s.geom)\
AND ST_DWithin(p.geom, v.geom,0.000524
Моя следующая идея состояла в том, чтобы просто изменить запрос и сделать его так, чтобы он вставлял только ближайшего соседа, основываясь на боковом соединении, но этот невероятно медленный по сравнению с первым (он берет на себянеделя, чтобы закончить против нескольких часов от другого).
INSERT INTO result(id_state, name_m, id_m, type_l, \
name_l, id_l, cab_l, name_c, \
type_d, di, \
numext, port, id5, gid, pro, \
Y, X, geom, distance,cat_v, type_v, vi, id_v) \
(SELECT v1.* \
FROM portales p , \
lateral(select '{0}'m.name, l.cv, l.type,l.name, l.loc, l.cab, \
c.name,d.type, s.distr, \
p.numext, p.portal, p.id5, p.gid, p.pro, \
ST_Y(p.geom), ST_X(p.geom) ,p.geom, ST_DISTANCE(p.geom,v.geom), v.cat, v.type, v.name, v.id, \
FROM m, l, c, v, \
d, s \
WHERE p.state = '{0}' \
AND left(m.cm,2) = '{0}' \
AND p.id5 = {1} \
AND st_dwithin(p.geom, m.geom, 0) \
AND ST_INTERSECTS(p.geom, m.geom) \
AND st_dwithin(p.geom, l.geom, 0) \
AND ST_INTERSECTS(p.geom, l.geom) \
AND st_dwithin(p.geom, d.geom, 0) \
AND ST_INTERSECTS(p.geom, d.geom) \
AND st_dwithin(p.geom, s.geom, 0) \
AND ST_INTERSECTS(p.geom, s.geom) \
AND ST_DWithin(p.geom, v.geom, 0.000524) \
Order by p.id5, st_distance(p.geom,v.geom) limit 1) as v1)
Итак, как вы, ребята, видите, ни один из них не является действительным по пространственно-временным причинам, даже если они теоретически работают.
Я думал о том, чтобы перейти к первому (второй слишком медленный) и ограничить вставку каким-либо условием, таким как UPDATE, где ID5 такой же, а расстояние меньше существующего.(в конфликте?), но я не знаю, насколько это будет эффективно, и я не могу понять, как это сделать.С другой стороны, вторая решает проблему дублирования с самого начала, но она невероятно медленная, поэтому, если есть способ просто ускорить это с недели до нескольких часов / одного дня, это было бы одинаково здорово..
Просто, чтобы вы, ребята, увидели, что я получаю в результате первого сценария, прежде чем я удаляю дубликаты, это:
name_c id5 distance
A 1 8.500
B 1 0.003
C 1 0.002
A 1 8.500
B 1 0.003
C 1 0.002
A 1 8.500
B 1 0.003
C 1 0.002
Затем, в конце концов, он меняется на следующий id5и продолжает идти.Я действительно не знаю, почему он производит так много дубликатов.Скорость первого скрипта хорошая, мне просто нужно, чтобы в таблицу не вставлялось столько дубликатов.
Заранее спасибо.