Я хотів би мати можливість генерувати випадкові bytea
поля довільної довжини (<1Gb) для заповнення даних тесту.
Який найкращий спосіб зробити це?
Я хотів би мати можливість генерувати випадкові bytea
поля довільної довжини (<1Gb) для заповнення даних тесту.
Який найкращий спосіб зробити це?
Відповіді:
Покращуючи відповідь Джека Дугласа, щоб уникнути необхідності циклічного циклу PL / PgSQL та об'єднання байтів, ви можете використовувати:
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';
Це проста SQL
функція, яку дешевше викликати, ніж PL / PgSQL.
Різниця в продуктивності завдяки зміненому методу агрегації величезна для більших bytea
значень. Хоча оригінальна функція насправді до 3 разів швидша для розмірів <50 байт, ця масштабується набагато краще для більших значень.
Або скористайтеся функцією розширення C :
Я реалізував генератор випадкових байтів як просту функцію розширення C. Це в моєму сховищі скрап-коду на GitHub . Дивіться README там.
Це вражає продуктивністю вищевказаної версії 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);
треба FROM generate_series(1, $1);
. Ви пробували рекурсію? Моє обмежене тестування передбачає, що цей масштаб краще:
/dev/urandom
в /var/lib/pgsql/data
і читати його з pg_read_file()
бонусним божевільними очками, але , до жаль , pg_read_file()
читаю text
введення з допомогою перетворення кодування, тому він не може читати BYTEA. Якщо вам дуже потрібна максимальна швидкість, напишіть функцію C
розширення, яка використовує швидкий генератор псевдовипадкових чисел для отримання бінарних даних і оберне байтову дату навколо буфера :-)
random_bytea
. github.com/ringerc/scrapcode/tree/master/postgresql/…
Я хотів би мати можливість генерувати випадкові байтові поля довільної довжини
Ця функція буде виконувати цю функцію, але 1 Гб знадобиться тривалий час, оскільки вона не масштабується лінійно з вихідною довжиною:
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;$$;
вихідний тест:
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 тут