我有多个这样的更新查询。我正在使用postgis和pg_trgm扩展来提供函数similarity
和ST_Buffer
以及&&
运算符,但这并不重要,因为它们可以很容易地被其他条件替换。至关重要的是,我为每一行有一个单独的选择子查询,但没有为每个更新语句。
UPDATE table0 AS t0
SET value1 = value1 OR
(SELECT coalesce(BOOL_OR(t1.value1),FALSE)
FROM table1 AS t1
WHERE similarity(t1.name,t0.name)>0.7 AND t1.geom && ST_Buffer(t0.geom, 500, 3))
WHERE t0.need_update;
UPDATE table0 AS t0
SET value2 = value2 OR
(SELECT coalesce(BOOL_OR(t1.value2),FALSE)
FROM table1 AS t1
WHERE similarity(t1.name,t0.name)>0.7 AND t1.geom && ST_Buffer(t0.geom, 500, 3))
WHERE t0.need_update;
...
现在,我想加快这些查询的速度。 table1
和table2
都很安静(数百万行)。大部分查询时间可能都用于子查询,并且由于每个更新语句的查询时间都相同,因此我很确定我可以通过组合所有查询来实现。
但是如何?
我已经尝试过以下操作:
UPDATE table0 AS t0
SET value1 = value1 OR t1val1, value2 = value2 OR t1val2
FROM
(SELECT coalesce(BOOL_OR(t1.value1),FALSE) AS t1val1, coalesce(BOOL_OR(t1.value2),FALSE) AS t1val2
FROM table1 AS t1
WHERE similarity(t1.name,t0.name)>0.7 AND t1.geom && ST_Buffer(t0.geom, 500, 3)) AS subquery
WHERE t0.need_update;
但这会导致:
ERROR: invalid reference to FROM-clause entry for table "t0"
LINE 6: WHERE similarity(t1.name,t0.name)>0.7 and t1.geom && ST...
^
HINT: There is an entry for table "t0", but it cannot be referenced from this part of the query.
有什么想法吗?感谢您的帮助!
答案 0 :(得分:0)
getRandomColor(randomColor) {
this.color = '#'; // <-----------
for (var i = 0; i < 6; i++) {
this.color += this.letters[Math.floor(Math.random() * 16)];
}
}
是错误的语法;您不应重复使用SET value1 = value1 OR t1val1, SET value2 = value2 OR t1val2
关键字
SET
,我还将别名添加到了引用中。
此更新(通常)将布尔列从False更改为True:
SET value1 = t0.value1 OR subquery.t1val1
, value2 = t0.value2 OR subquery.t1val2
...
同样,直接使用UPDATE table0 AS t0
SET value1 = True
WHERE t0.value1 = False -- Only change it if it is not already set
AND t0.need_update
AND EXISTS (SELECT *
FROM table1 AS t1
WHERE similarity(t1.name,t0.name) > 0.7
-- I think you want st_dwithin() here; not sure
AND t1.geom && ST_Buffer(t0.geom, 500, 3)
)
;
的布尔结果:
EXISTS()
顺便说一句:我认为,您还需要一个额外的条件来防止t0和t1引用相同的记录,例如:
UPDATE table0 AS t0
SET value1 = EXISTS (SELECT *
FROM table1 AS t1
WHERE similarity(t1.name,t0.name) > 0.7
AND t1.geom && ST_Buffer(t0.geom, 500, 3)
)
WHERE t0.value1 = False -- Only change it if it is not already set
AND t0.need_update
;