web-dev-qa-db-ja.com

Postgres FOR LOOP

テーブルから15,000 IDのランダムサンプルを25個取得しようとしています。毎回手動でrunを押す代わりに、ループを実行しようとしています。私が完全に理解しているのはPostgresの最適な使用法ではありませんが、私が持っているツールです。これは私がこれまでに持っているものです:

for i in 1..25 LOOP
   insert into playtime.meta_random_sample
   select i, ID
   from   tbl
   order  by random() limit 15000
end loop
45
user2840106

Proceduralloops のような要素は一部ではありませんSQL言語であり、手続き型言語の本体内でのみ使用できます 関数手順 (Postgres 11以降)または DO 、そのような追加要素はそれぞれの手続き言語によって定義されます。デフォルトは PL/pgSQL ですが、 他にもあります です。

Plpgsqlを使用した例:

DO
$do$
BEGIN 
   FOR i IN 1..25 LOOP
      INSERT INTO playtime.meta_random_sample
         (col_i, col_id)                       -- declare target columns!
      SELECT  i,     id
      FROM   tbl
      ORDER  BY random()
      LIMIT  15000;
   END LOOP;
END
$do$;

ループで解決できる多くのタスクについては、角を曲がったところに短くて速いset-basedソリューションがあります。あなたの例に相当する純粋なSQL:

INSERT INTO playtime.meta_random_sample (col_i, col_id)
SELECT t.*
FROM   generate_series(1,25) i
CROSS  JOIN LATERAL (
   SELECT i, id
   FROM   tbl
   ORDER  BY random()
   LIMIT  15000
   ) t;

generate_series() について:

ランダム選択のパフォーマンスの最適化について:

108

以下は使用可能な例です。

create temp table test2 (
  id1  numeric,
  id2  numeric,
  id3  numeric,
  id4  numeric,
  id5  numeric,
  id6  numeric,
  id7  numeric,
  id8  numeric,
  id9  numeric,
  id10 numeric) 
with (oids = false);

do
$do$
declare
     i int;
begin
for  i in 1..100000
loop
    insert into test2  values (random(), i * random(), i / random(), i + random(), i * random(), i / random(), i + random(), i * random(), i / random(), i + random());
end loop;
end;
$do$;
0
Gabriel