Ich möchte in der Lage sein, zufällige byteaFelder beliebiger Länge (<1 GB) zum Auffüllen von Testdaten zu generieren .
Wie geht das am besten?
Ich möchte in der Lage sein, zufällige byteaFelder beliebiger Länge (<1 GB) zum Auffüllen von Testdaten zu generieren .
Wie geht das am besten?
Antworten:
Wenn Sie die Antwort von Jack Douglas verbessern, um PL / PgSQL-Schleifen und die Verkettung von Bytes zu vermeiden, können Sie Folgendes verwenden:
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 ist eine einfache SQLFunktion, die billiger aufzurufen ist als PL / PgSQL.
Der Leistungsunterschied aufgrund der geänderten Aggregationsmethode ist bei größeren byteaWerten immens . Obwohl die ursprüngliche Funktion bei Größen <50 Byte bis zu dreimal schneller ist, skaliert diese Funktion bei größeren Werten viel besser.
Oder verwenden Sie eine C-Erweiterungsfunktion :
Ich habe einen Zufalls-Bytea-Generator als einfache C-Erweiterungsfunktion implementiert. Es befindet sich in meinem Scrapcode-Repository auf GitHub . Siehe dort die README.
Es macht die Leistung der obigen SQL-Version zunichte:
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);muss sein FROM generate_series(1, $1);. Haben Sie Rekursion versucht? Meine begrenzten Tests deuten darauf hin, dass dies besser skaliert:
/dev/urandomzu verknüpfen /var/lib/pgsql/dataund zu lesen, pg_read_file()um verrückte Bonuspunkte zu erhalten, aber leider pg_read_file()liest ich textEingaben über eine Codierungskonvertierung, sodass es nicht bytea lesen kann. Wenn Sie wirklich maximale Geschwindigkeit wollen, schreiben Sie eine CErweiterungsfunktion, die einen schnellen Pseudozufallszahlengenerator verwendet, um Binärdaten zu erzeugen und ein Bytea-Datum um den Puffer zu wickeln :-)
random_bytea. github.com/ringerc/scrapcode/tree/master/postgresql/…
Ich möchte zufällige Bytea-Felder beliebiger Länge erzeugen können
Diese Funktion wird es tun, aber 1 GB wird lange dauern, da es nicht linear mit der Ausgabelänge skaliert:
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;$$;
Ausgangstest:
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 hier