Eu gostaria de poder gerar bytea
campos aleatórios de comprimento arbitrário (<1 GB) para preencher dados de teste.
Qual a melhor maneira para fazer isto?
Eu gostaria de poder gerar bytea
campos aleatórios de comprimento arbitrário (<1 GB) para preencher dados de teste.
Qual a melhor maneira para fazer isto?
Respostas:
Aprimorando a resposta de Jack Douglas para evitar a necessidade de loop PL / PgSQL e concatenação bytea, você pode usar:
CREATE OR REPLACE FUNCTION random_bytea(bytea_length integer)
RETURNS bytea AS $body$
SELECT decode(string_agg(lpad(to_hex(width_bucket(random(), 0, 1, 256)-1),2,'0') ,''), 'hex')
FROM generate_series(1, $1);
$body$
LANGUAGE 'sql'
VOLATILE
SET search_path = 'pg_catalog';
É uma SQL
função simples , mais barata de chamar do que PL / PgSQL.
A diferença no desempenho devido ao método de agregação alterado é imensa para bytea
valores maiores . Embora a função original seja até 3x mais rápida para tamanhos <50 bytes, esta é dimensionada muito melhor para valores maiores.
Ou use uma função de extensão C :
Eu implementei um gerador de bytea aleatório como uma função de extensão C simples. Está no meu repositório de scrapcode no GitHub . Veja o README lá.
Ele reduz o desempenho da versão SQL acima:
regress=# \a
regress=# \o /dev/null
regress=# \timing on
regress=# select random_bytea(2000000);
Time: 895.972 ms
regress=# drop function random_bytea(integer);
regress=# create extension random_bytea;
regress=# select random_bytea(2000000);
Time: 24.126 ms
FROM generate_series(0, $1);
precisa ser FROM generate_series(1, $1);
. Você já tentou recursão? Meu teste limitado implica que isso é melhor:
/dev/urandom
para /var/lib/pgsql/data
e lê-lo com pg_read_file()
para o bônus pontos loucas, mas, infelizmente, pg_read_file()
lê text
entrada através de uma conversão de codificação, por isso não pode ler bytea. Se você realmente quer velocidade máxima, escrever uma C
função de extensão que utiliza um gerador de números pseudo-aleatório rápido para produzir dados binários e enrole um dado bytea ao redor do tampão :-)
random_bytea
. github.com/ringerc/scrapcode/tree/master/postgresql/…
Eu gostaria de poder gerar campos de bytea aleatórios de comprimento arbitrário
Esta função fará isso, mas 1Gb levará muito tempo porque não é dimensionado linearmente com o comprimento da saída:
create function random_bytea(p_length in integer) returns bytea language plpgsql as $$
declare
o bytea := '';
begin
for i in 1..p_length loop
o := o||decode(lpad(to_hex(width_bucket(random(), 0, 1, 256)-1),2,'0'), 'hex');
end loop;
return o;
end;$$;
teste de saída:
select random_bytea(2);
/*
|random_bytea|
|:-----------|
|\xcf99 |
*/
select random_bytea(10);
/*
|random_bytea |
|:---------------------|
|\x781b462c3158db229b3c|
*/
select length(random_bytea(100000))
, clock_timestamp()-statement_timestamp() time_taken;
/*
|length|time_taken |
|-----:|:--------------|
|100000|00:00:00.654008|
*/
dbfiddle aqui