試してみてください。click
EDIT
@kordiroko申し訳ありません:
WITH arrays AS(
SELECT * from
unnest(
ARRAY[20, 30],
ARRAY[275, 375]
) as xy(x,y)
)
UPDATE t1
SET c3 = a.y
FROM arrays a
WHERE c2 = a.x;
ここunnest
機能の説明を参照してください。あなたのソリューションを変更して一日中使いました。 動作させることができませんでした。
古いPostgreSQLバージョンを使用している可能性があります。これがあれば、私に教えてください
create table t1(
c2 BIGINT,
c3 bigint
);
insert into t1(c2, c3)
select x, x * 100
from generate_series(1,1000000) x;
CREATE OR REPLACE FUNCTION updatefunc1(BigInt[], BigInt[])
RETURNS void as $$
BEGIN
FOR i IN array_lower($1, 1) .. array_upper($1, 1)
LOOP
update t1
SET c3 = $2[i]
WHERE c2 = $1[i];
END LOOP;
END;
$$
LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION updatefunc2(BigInt[], BigInt[])
RETURNS void as $$
BEGIN
WITH arrays AS(
SELECT * from
unnest($1, $2 ) as xy(x,y)
)
UPDATE t1
SET c3 = a.y
FROM arrays a
WHERE c2 = a.x;
END;
$$
LANGUAGE plpgsql;
select updatefunc1(ARRAY[20], ARRAY[275]);
select updatefunc2(ARRAY[30], ARRAY[555]);
select * from t1 where c2 in (20,30);
:私は、バージョン9.5でそれをテストし、それだけで、コピー/貼り付け、それが仕事を得るために私に数分だけのカップルを取り、クエリ内の2つのパラメータを変更します正しいか、より良い解決策があります。
これはちょっと遅いです。それが終わる12秒かかりました
select updatefunc1(
array(select * from generate_series(1,100)),
array(select 22222 from generate_series(1,100))
);
:
は、私が唯一の100レコードのためにあなたの機能をテストし
の検索結果を(コスト= 20.00..20.31行= 1、幅= 0)(実際 時間= 12259.095..12259.096行= 1つのループ= 1)出力: updatefunc1(($ 0):: BIGINT []、($ 1):: BIGINT [])InitPlan 1(戻り$ 0)
は今私の関数にそれを比較するが、100.000レコードについて:
結果(コスト= 20.00..20.31行= 1、幅= 0):
select updatefunc2(
array(select * from generate_series(1,100000)),
array(select 22222 from generate_series(1,100000))
);
結果は、1秒150ミリ秒であります(実際の 時間= 1150.018 ..1150.123行= 1つのループ= 1)出力: updatefunc2(($ 0):: BIGINT []、($ 1):: BIGINT [])InitPlan 1($ 0を返し)
上記の結果の意味、そのあなたの関数は次のとおりです。
(11/100)/(1.150/100000)= 10434,78
回のslooooooooooooooooooooooooooweeeeeeeeeeeeeeeeeeeeeeer、
および%で、これは私のバージョンは9.2.15です
EDIT 2
のみ104.34万%遅くなります。
CREATE OR REPLACE FUNCTION updatefunc3(BigInt[], BigInt[])
RETURNS void as $$
BEGIN
WITH arrays AS(
SELECT arr1[ rn ] as x, arr2[ rn ] as y
FROM (
SELECT $1 as arr1, $2 as arr2, generate_subscripts($1, 1) As rn
) x
)
UPDATE t1
SET c3 = a.y
FROM arrays a
WHERE c2 = a.x;
END;
$$
LANGUAGE plpgsql;
select updatefunc3(ARRAY[40,82,77], ARRAY[333,654]);
select * from t1 where c2 in (40,82,77);
そしてuptadint 100,000行の速度テストは次のとおりです:
select updatefunc3(
array(select * from generate_series(1,100000)),
array(select 22222 from generate_series(1,100000))
);
それは以下
のPostgreSQLの以前のverionsに取り組む必要があるバージョンです構文エラーをスローします結果(コスト= 20.00..20.31行= 1つの幅= 0)(実際の 時間= 1361.358 ..1361.460行= 1つのループ= 1)出力: updatefunc3(($ 0):: BIGINT []、($ 1):: BIGINT [])InitPlan 1($ 0を返します)
100kの行を更新する時間が1.5秒
を下回っています
EDIT 3
@kordiko:あなたのクエリがそんなに優れている理由を教えてくださいでした。 私の関数は各行を通り、要素を1つずつ更新します。 あなたの関数も同じように見えます。それはすべての 同等の行がクエリで同時に編を更新していることです。
あなたの関数は要素一つ一つを更新しながら、私の関数は、関係なく、配列の要素数の一つだけ updateコマンドを実行しますので、これはです - 100個の要素のためには、100の更新コマンドを実行します。 1000要素に対して、1000更新コマンドを実行します。
私はなく、任意のインデックスのない、1000000行をテーブルの上に私のテストを行ってきました。私の機能では、更新プログラムはテーブルの内容を1回だけ読み込み(テーブル全体のスキャンを行います)、一致する行を更新します。関数は100回の更新を実行し、それぞれが完全な表スキャンを行います。
作成およびインデックスcol2
に、そしてあなたの関数の速度は、この試験の要素数が100000に100から増加していることに注意してください(下記のテストを参照してください、劇的inceases場合:今
create INDEX t1_c2_ix on t1(c2);
select updatefunc1(
array(select * from generate_series(1,100000)),
array(select 22222 from generate_series(1,100000))
);
Result (cost=20.00..20.31 rows=1 width=0) (actual time=**3430.536**..3430.636 rows=1 loops=1)
Output: updatefunc1(($0)::bigint[], ($1)::bigint[])
InitPlan 1 (returns $0)
時間は約3.5秒である
とインデックスを作成した後、私の機能のテスト:。
select updatefunc3(
array(select * from generate_series(1,100000)),
array(select 22222 from generate_series(1,100000))
);
結果(コスト= 20.00..20.31行= 1、幅= 0)(実際の時間= 1270.619。 .1270.724行= 1つのループ= 1) 出力:updatefunc3(($ 0):: BIGINT []、($ 1):: BIGINT []) InitPlan 1($ 0を返し)
時間が、同じままでありますあなたの機能よりもまだ100%速いです。
@kordiroko申し訳ありません。あなたのソリューションを変更して一日中使いました。それを動作させることができませんでした。 – gudge
私はアンガーを更新しました。それを見てください。 – krokodilko
私のバージョンは9.2.15です。構文エラーが発生します。 – gudge