J'aimerais pouvoir générer des byteachamps 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 byteachamps 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 SQLfonction 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 byteavaleurs 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/urandomdans /var/lib/pgsql/dataet de la lecture avec pg_read_file()des points bonus fous, mais malheureusement , se pg_read_file()lit textentrée par une conversion d'encodage, donc il ne peut pas lire bytea. Si vous voulez vraiment la vitesse maximale, écrivez une Cfonction 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