Me gustaría poder generar bytea
campos aleatorios de longitud arbitraria (<1Gb) para llenar datos de prueba.
Cual es la mejor manera de hacer esto?
Me gustaría poder generar bytea
campos aleatorios de longitud arbitraria (<1Gb) para llenar datos de prueba.
Cual es la mejor manera de hacer esto?
Respuestas:
Mejorando la respuesta de Jack Douglas para evitar la necesidad de bucles PL / PgSQL y concatenación bytea, puede 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';
Es una SQL
función simple que es más barata de llamar que PL / PgSQL.
La diferencia en el rendimiento debido al método de agregación modificado es inmensa para bytea
valores más grandes . Aunque la función original es hasta 3 veces más rápida para tamaños <50 bytes, esta escala mucho mejor para valores más grandes.
O use una función de extensión C :
He implementado un generador bytea aleatorio como una simple función de extensión C. Está en mi repositorio de código de desecho en GitHub . Ver el archivo Léame allí.
Desnuda el rendimiento de la versión SQL anterior:
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);
necesita ser FROM generate_series(1, $1);
. ¿Has probado la recursividad? Mi prueba limitada implica que esto se escala mejor:
/dev/urandom
en /var/lib/pgsql/data
y leer con pg_read_file()
de puntos de bonificación locos, pero por desgracia pg_read_file()
lee text
entrada a través de una conversión de codificación, por lo que no puede leer bytea. Si realmente desea una velocidad máxima, escriba una C
función de extensión que use un generador rápido de números pseudoaleatorios para producir datos binarios y ajuste un dato bytea alrededor del búfer :-)
random_bytea
. github.com/ringerc/scrapcode/tree/master/postgresql/…
Me gustaría poder generar campos bytea aleatorios de longitud arbitraria
Esta función lo hará, pero 1Gb tomará mucho tiempo porque no se escala linealmente con la longitud de salida:
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;$$;
prueba de salida:
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 aquí