Ich möchte in der Lage sein, zufällige bytea
Felder 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 bytea
Felder 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 SQL
Funktion, die billiger aufzurufen ist als PL / PgSQL.
Der Leistungsunterschied aufgrund der geänderten Aggregationsmethode ist bei größeren bytea
Werten 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/urandom
zu verknüpfen /var/lib/pgsql/data
und zu lesen, pg_read_file()
um verrückte Bonuspunkte zu erhalten, aber leider pg_read_file()
liest ich text
Eingaben über eine Codierungskonvertierung, sodass es nicht bytea lesen kann. Wenn Sie wirklich maximale Geschwindigkeit wollen, schreiben Sie eine C
Erweiterungsfunktion, 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