Tôi muốn có thể tạo các bytea
trường ngẫu nhiên có độ dài tùy ý (<1Gb) để điền dữ liệu thử nghiệm.
Cách nào là tốt nhất để thực hiện việc này?
Tôi muốn có thể tạo các bytea
trường ngẫu nhiên có độ dài tùy ý (<1Gb) để điền dữ liệu thử nghiệm.
Cách nào là tốt nhất để thực hiện việc này?
Câu trả lời:
Nâng cao câu trả lời của Jack Douglas để tránh sự cần thiết phải lặp PL / PGQuery và kết nối tạm thời, bạn có thể sử dụng:
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';
Đây là một SQL
chức năng đơn giản mà rẻ hơn so với PL / PGQuery.
Sự khác biệt về hiệu suất do phương pháp tổng hợp thay đổi là rất lớn đối với các bytea
giá trị lớn hơn . Mặc dù chức năng ban đầu thực sự nhanh hơn tới 3 lần đối với kích thước <50 byte, nhưng chức năng này có tỷ lệ tốt hơn nhiều đối với các giá trị lớn hơn.
Hoặc sử dụng chức năng mở rộng C :
Tôi đã triển khai một trình tạo bytea ngẫu nhiên như một hàm mở rộng C đơn giản. Nó nằm trong kho lưu trữ mã số của tôi trên GitHub . Xem README ở đó.
Nó ngăn chặn hiệu suất của phiên bản SQL trên:
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);
cần phải có FROM generate_series(1, $1);
. Bạn đã thử đệ quy chưa? Thử nghiệm hạn chế của tôi ngụ ý rằng quy mô này tốt hơn:
/dev/urandom
vào /var/lib/pgsql/data
và đọc nó với pg_read_file()
cho tiền thưởng điểm điên, nhưng tiếc là pg_read_file()
đọc text
đầu vào thông qua một chuyển đổi mã hóa, vì vậy nó không thể đọc bytea. Nếu bạn thực sự muốn tốc độ tối đa, hãy viết C
hàm mở rộng sử dụng trình tạo số giả ngẫu nhiên nhanh để tạo dữ liệu nhị phân và bọc dữ liệu tạm thời xung quanh bộ đệm :-)
random_bytea
. github.com/ringerc/scrapcode/tree/master/postgresql/ từ
Tôi muốn có thể tạo các trường tạm thời ngẫu nhiên có độ dài tùy ý
Hàm này sẽ làm điều đó, nhưng 1Gb sẽ mất nhiều thời gian vì nó không mở rộng tuyến tính với độ dài đầu ra:
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;$$;
kiểm tra đầu ra:
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 ở đây