У меня есть требование, где я должен сохранить записи по курсу 10 000 записей/секунда в базу данных (с индексацией на нескольких полях). Число столбцов в одной записи равняется 25. Я делаю пакетную вставку 100 000 записей в одном блоке транзакции. Для улучшения уровня вставки я изменил табличную область от диска до RAM.With, которого я могу достигнуть, только 5 000 вставляют в секунду.
Я также сделал следующее настраивание конфигурации пост-ГРЭС:
Другая информация:
Я задаюсь вопросом, почему единственный запрос на вставку занимает приблизительно 0,2 мс в среднем, когда база данных ничего не пишет на диске (поскольку я использую основанную на RAM табличную область). Есть ли что-то, что я делаю неправильно?
Help ценится.
Prashant
\ COPY schema.temp_table FROM /tmp/data.csv С CSV
Для больших объемов данных:
SELECT
. Другими словами, попытайтесь согласовать физическую модель с логической. CLUSTER
(самый важный столбец слева). Например: CREATE UNIQUE INDEX measurement_001_stc_index ON climate.measurement_001 USING btree (station_id, taken, category_id); ALTER TABLE climate.measurement_001 CLUSTER ON measurement_001_stc_index;
На машине с 4 ГБ ОЗУ я сделал следующее ...
Сообщите ядру, что программы могут использовать большие объемы общей памяти:
sysctl -w kernel.shmmax=536870912
sysctl -p /etc/sysctl.conf
/etc/postgresql/8.4/main/postgresql.conf
и установите: shared_buffers = 1 ГБ temp_buffers = 32 МБ work_mem = 32 МБ maintenance_work_mem = 64 МБ seq_page_cost = 1.0 random_page_cost = 2.0 cpu_index_tuple_cost = 0,001 Effective_cache_size = 512 МБ checkpoint_segments = 10
Например, у вас есть данные о погоде, разделенные на разные категории. Вместо того, чтобы иметь одну чудовищную таблицу, разделите ее на несколько таблиц (по одной на каждую категорию).
CREATE TABLE climate.measurement
(
id bigserial NOT NULL,
taken date NOT NULL,
station_id integer NOT NULL,
amount numeric(8,2) NOT NULL,
flag character varying(1) NOT NULL,
category_id smallint NOT NULL,
CONSTRAINT measurement_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
CREATE TABLE climate.measurement_001
(
-- Inherited from table climate.measurement_001: id bigint NOT NULL DEFAULT nextval('climate.measurement_id_seq'::regclass),
-- Inherited from table climate.measurement_001: taken date NOT NULL,
-- Inherited from table climate.measurement_001: station_id integer NOT NULL,
-- Inherited from table climate.measurement_001: amount numeric(8,2) NOT NULL,
-- Inherited from table climate.measurement_001: flag character varying(1) NOT NULL,
-- Inherited from table climate.measurement_001: category_id smallint NOT NULL,
CONSTRAINT measurement_001_pkey PRIMARY KEY (id),
CONSTRAINT measurement_001_category_id_ck CHECK (category_id = 1)
)
INHERITS (climate.measurement)
WITH (
OIDS=FALSE
);
Увеличьте статистику таблицы для важных столбцов:
ALTER TABLE climate.measurement_001 ALTER COLUMN taken SET STATISTICS 1000;
ALTER TABLE climate.measurement_001 ALTER COLUMN station_id SET STATISTICS 1000;
Не забудьте ВАКУУМ
и АНАЛИЗ
] после.
вы делаете вставку как серию
INSERT INTO tablename (...) VALUES (...);
INSERT INTO tablename (...) VALUES (...);
...
или как одно кратное -row insert:
INSERT INTO tablename (...) VALUES (...),(...),(...);
второй будет значительно быстрее на 100k строках.
источник: http://kaiv.wordpress.com/2007/07/19/faster-insert-for-multiple-rows/
Я предлагаю вам использовать COPY
вместо INSERT
.
Вам также следует настроить ваш файл postgresql.conf.
Читайте о http://wiki.postgresql.org/wiki/Performance_Optimization
Вы поместили xlog (сегменты WAL) также на RAM-диск? Если нет, то вы все еще пишете на диск. А как насчет настроек wal_buffers, checkpoint_segments и т.д. ? Вы должны попытаться получить все ваши 100 000 записей (ваша одна транзакция) в ваших wal_buffers. Увеличение этого параметра может привести к тому, что PostgreSQL запросит больше общей памяти System V, чем позволяет конфигурация по умолчанию вашей операционной системы.