Tôi muốn có thể tạo các byteatrườ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 byteatrườ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 SQLchứ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 byteagiá 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/urandomvào /var/lib/pgsql/datavà đọ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 Chà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