J'aimerais pouvoir générer des bytea
champs aléatoires de longueur arbitraire (<1 Go) pour remplir les données de test.
Quelle est la meilleure façon de procéder?
J'aimerais pouvoir générer des bytea
champs aléatoires de longueur arbitraire (<1 Go) pour remplir les données de test.
Quelle est la meilleure façon de procéder?
Réponses:
En améliorant la réponse de Jack Douglas pour éviter le besoin de bouclage PL / PgSQL et de concaténation de bytea, vous pouvez utiliser:
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';
C'est une SQL
fonction simple qui coûte moins cher à appeler que PL / PgSQL.
La différence de performances due à la méthode d'agrégation modifiée est immense pour les bytea
valeurs plus importantes . Bien que la fonction d'origine soit en réalité jusqu'à 3 fois plus rapide pour les tailles <50 octets, celle-ci évolue beaucoup mieux pour les valeurs plus grandes.
Ou utilisez une fonction d'extension C :
J'ai implémenté un générateur de bytea aléatoire comme une simple fonction d'extension C. C'est dans mon dépôt de scrapcode sur GitHub . Voir le README là-bas.
Il annule les performances de la version SQL ci-dessus:
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);
doit être FROM generate_series(1, $1);
. Avez-vous essayé la récursivité? Mes tests limités impliquent que cela évolue mieux:
/dev/urandom
dans /var/lib/pgsql/data
et de la lecture avec pg_read_file()
des points bonus fous, mais malheureusement , se pg_read_file()
lit text
entrée par une conversion d'encodage, donc il ne peut pas lire bytea. Si vous voulez vraiment la vitesse maximale, écrivez une C
fonction d'extension qui utilise un générateur de nombres pseudo-aléatoire rapide pour produire des données binaires et enrouler une donnée bytea autour du tampon :-)
random_bytea
. github.com/ringerc/scrapcode/tree/master/postgresql/…
J'aimerais pouvoir générer des champs aléatoires de longueur arbitraire
Cette fonction le fera, mais 1 Go prendra du temps car il ne se met pas à l'échelle linéairement avec la longueur de sortie:
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;$$;
test de sortie:
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 ici