Postgresql: как эффективно заполнять таблицу с 10 миллионами строк со случайной строкой

Вопрос:У меня есть таблица со схемой: test1 (id integer primary key , padding text) (есть индекс на id) Я хочу иметь 10 миллионов строк со случайным заполнением (длина заполнения меньше 1024 знаков). Как быстро его сгенерировать и вставить в таблицу? Я пытаюсь прямо сейчас это решение: insert into test1 (select *, random_string(1024) from generate_series(0, 10000000));

Вопрос:

У меня есть таблица со схемой:

test1 (id integer primary key , padding text)

(есть индекс на id)

Я хочу иметь 10 миллионов строк со случайным заполнением (длина заполнения меньше 1024 знаков).
Как быстро его сгенерировать и вставить в таблицу?

Я пытаюсь прямо сейчас это решение:

insert into test1 (select *, random_string(1024) from generate_series(0, 10000000));

где random_string – функция:

create or replace function random_string(length integer) returns text as $$ declare chars text[] := ‘{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}’; result text := »; i integer := 0; length2 integer := (select trunc(random() * length + 1)); begin if length2 < 0 then raise exception ‘Given length cannot be less than 0’; end if; for i in 1..length2 loop result := result || chars[1+random()*(array_length(chars, 1)-1)]; end loop; return result; end; $$ language plpgsql;

Кажется, что postgresql создает временную таблицу, и только генерация этой временной таблицы займет 2 часа.

Лучший ответ:

Если эффективность является большой проблемой, тогда может возникнуть больше смысла генерировать ваши данные на другом языке, который более тщательно оптимизируется, а затем использовать оператор COPY для копирования данных в таблицу. Например, если вы находитесь в системе Linux-y, вы можете сохранить эту программу C99 как generate_test1_data.c:

#include <stdio.h> #include <stdlib.h> #include <string.h> #define MIN_ID 0 #define MAX_ID 10000000 #define MAX_LEN 1024 #define CHARS «0123456789» «ABCDEFGHIJKLMNOPQRSTUVWXYZ» «abcdefghijklmnopqrstuvwxyz» int main() { char const * const chars = CHARS; int const num_chars = strlen(chars); printf(«COPY test1 FROM STDIN;n»); for(int i = MIN_ID; i <= MAX_ID; ++i) { printf(«%dt», i); // can be optimized if needed int const len = rand() % MAX_LEN + 1; for(int j = 0; j < len; ++j) putchar(chars[rand() % num_chars]); putchar(‘n’); } printf(«\.n»); return 0; }

а затем выполните следующие команды:

gcc -std=c99 -Wall generate_test1_data.c -o generate_test1_data ./generate_test1_data > populate_test1.sql psql -U … -d … -f populate_test1.sql

В окне разработки, которое мне доступно в данный момент, все это займет около десяти минут (или, по крайней мере, я попробовал это на сотых долях, и это заняло менее шести секунд). Это довольно мощная коробка, поэтому в вашей системе это может занять больше времени. может быть, даже намного дольше? но, я думаю, не так давно, как ваш нынешний подход.

Ответ №1

Самый быстрый способ сделать это – это, вероятно,

  • создать таблицу без ограничений,
  • используйте внешнюю программу для генерации случайных данных,
  • используйте COPY, чтобы загрузить его в таблицу,
  • затем добавьте ограничения.
Оцените статью
Добавить комментарий