Chciałbym móc generować losowe bytea
pola o dowolnej długości (<1 Gb) do wypełniania danych testowych.
Jak najlepiej to zrobić?
źródło
Chciałbym móc generować losowe bytea
pola o dowolnej długości (<1 Gb) do wypełniania danych testowych.
Jak najlepiej to zrobić?
Ulepszając odpowiedź Jacka Douglasa, aby uniknąć potrzeby zapętlania PL / PgSQL i konkatenacji bajtów, możesz użyć:
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';
Jest to prosta SQL
funkcja, której wywołanie jest tańsze niż PL / PgSQL.
Różnica w wydajności spowodowana zmienioną metodą agregacji jest ogromna w przypadku większych bytea
wartości. Chociaż oryginalna funkcja jest nawet trzykrotnie szybsza dla rozmiarów <50 bajtów, ta funkcja skaluje się znacznie lepiej dla większych wartości.
Lub użyj funkcji rozszerzenia C :
Zaimplementowałem generator losowych bajtów jako prostą funkcję rozszerzenia C. Znajduje się w moim repozytorium scrapcode na GitHub . Zobacz README tam.
Nukuje wydajność powyższej wersji SQL:
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);
musi byćFROM generate_series(1, $1);
. Czy próbowałeś rekursji? Moje ograniczone testy sugerują, że skaluje się to lepiej:/dev/urandom
się/var/lib/pgsql/data
i czytając jąpg_read_file()
do premii szalonych punktów, ale niestetypg_read_file()
czytatext
wejście poprzez konwersję kodowania, więc nie może czytać bytea. Jeśli naprawdę chcesz maksymalnej prędkości, napisz funkcjęC
rozszerzającą, która używa szybkiego generatora liczb pseudolosowych do tworzenia danych binarnych i owijaj dane bajtowe wokół bufora :-)random_bytea
. github.com/ringerc/scrapcode/tree/master/postgresql/…Ta funkcja to zrobi, ale 1 Gb zajmie dużo czasu, ponieważ nie skaluje się liniowo z długością wyjściową:
test wyjściowy:
dbfiddle tutaj
źródło