我想UPDATE
表myTable
(335379行)中的几行。
CREATE OR REPLACE FUNCTION costs_f(
someFloat float) RETURNS void AS
$$
BEGIN
UPDATE ways
SET cost_time = CASE WHEN $1 = -1.0 THEN -1 ELSE anotherFloat * $1 END
FROM (SELECT w.gid AS id,
mc.name,
w.someCosts
FROM myTable mt
JOIN myClasses mc
ON mt.class_id = mc.class_id) AS tempTable
WHERE gid = id AND tempTable.name_name = $2;
END
$$
language 'plpgsql';
然后在另一个函数
中调用此函数CREATE OR REPLACE FUNCTION update_costs_f(
someFloat float) RETURNS void AS
$$
DECLARE
someArr varchar[] := ARRAY['a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l',
'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'ul', 'v'];
i text;
BEGIN
FOREACH i IN ARRAY someArr LOOP
PERFORM costs_f($1, i);
END LOOP;
END
$$
language 'plpgsql';
然后我做
SELECT update_costs_f(10.0);
然而,这需要很长时间! 有没有办法提高速度?
*注意:此代码是抽象的。在第二个函数中有更多ForEach
循环。我有几个阵列。
答案 0 :(得分:1)
正如@a_horse_with_no_name所说,您不应该运行多个更新语句。
我发现您PERFORM costs_f($1, i)
中的每封信都多次致电someArr
。而不是多次调用它,只需调用一次并使用in
运算符,例如:
AND tempTable.name_name in($2)
;
您应该将更新语句拆分为两个语句:
UPDATE ways
SET cost_time = -1.0 FROM tempTable
WHERE gid = id AND tempTable.name_name = $2 AND
$1 = -1.0 ;
UPDATE ways
SET cost_time =anotherFloat * $1 FROM tempTable
WHERE gid = id AND tempTable.name_name = $2 AND
NOT ($1 = -1.0) ;
注意:仅使用tempTable而不是完整的嵌套子句/别名
进行简化马上就可以看到你可以将条件name_name = $2
直接移到from aliased subquery
:
FROM (SELECT w.gid AS id,
mc.name,
w.someCosts
FROM myTable mt
JOIN myClasses mc
ON mt.class_id = mc.class_id
WHERE name_name = $2 ) AS tempTable
WHERE gid = id;
CREATE OR REPLACE FUNCTION update_costs_f(
someFloat float) RETURNS void AS
$$
DECLARE
someArr varchar[] := ARRAY['a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l',
'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'ul', 'v'];
i text;
BEGIN
PERFORM costs_f($1, someArr );
END
$$
language 'plpgsql';
CREATE OR REPLACE FUNCTION costs_f(
someFloat float) RETURNS void AS
$$
BEGIN
UPDATE ways
SET cost_time = -1.0
FROM (SELECT w.gid AS id,
mc.name,
w.someCosts
FROM myTable mt
JOIN myClasses mc
ON mt.class_id = mc.class_id
WHERE $1 = -1.0 AND gid = id AND tempTable.name_name = ANY($2);
) AS tempTable;
UPDATE ways
SET cost_time =anotherFloat * $1
FROM (SELECT w.gid AS id,
mc.name,
w.someCosts
FROM myTable mt
JOIN myClasses mc
ON mt.class_id = mc.class_id
WHERE NOT($1 = -1.0) AND gid = id AND tempTable.name_name =ANY($2);
) AS tempTable;
END
$$
language 'plpgsql';
您可以使用IF语句,以便不运行两个SQL更新语句...
请参阅:PostgreSQL IF statement 例如:
IF ($1 = -1.0) THEN
...
ELSE
...
END IF;