LINUX.ORG.RU
ФорумAdmin

PostgreSQL UPDATE

 


0

1

Есть не самый мощный компьютер под GNU/Linux с Intel i7-4790K, двумя винтами sata 10000 rpm. На нем PostgreSQL 9.4rc1. Машина вообще ничем не загружена.

Создаем таблицу:

CREATE TABLE test_update (id BIGSERIAL NOT NULL, c BIGINT NOT NULL, PRIMARY KEY(id));
INSERT INTO test_update (c) VALUES (0);
VACUUM FULL ANALYZE test_update;

Запускаем скрипт:

#!/bin/bash

echo -n > test.sql;

for (( i=0; i < 10000; i++));
do
        echo "UPDATE test_update SET c=c+1 WHERE id=1;" >> test.sql;
done

Запускаем тест:

$ time (psql --host="${SQL_HOST}" --port="${SQL_PORT}" --dbname="${SQL_DATABASE}" --username="${SQL_LOGIN}" -w -f test.sql > /dev/null)

real    1m1.441s
user    0m0.440s
sys     0m0.192s

В iotop postgres не поднимается выше 1341.77 K/s, при том что например dd if=/dev/zero of=trash bs=4096 дает 162.84 M/s

hdparm в тесте показывает 170.90 MB/sec

Тот же тест но при fsync = off отрабатывает за полсекунды. Но это не решение.

Вопрос: подскажите пожалуйста как ускорить UPDATE в Postgres?

Перемещено maxcom из talks

★★★★

В iotop postgres не поднимается выше 1341.77 K/s

а он и не будет большим ибо буферизация, плюс ты меняешь только одно значение в одной записи.

$ time (psql --host=«${SQL_HOST}» --port=«${SQL_PORT}» --dbname=«${SQL_DATABASE}» --username=«${SQL_LOGIN}» -w -f test.sql > /dev/null)

есть ощущение, что в таком варианте он не только 10000 раз запустит апдейт, но потом еще rollback будет ибо коммита не вижу.

echo «UPDATE test_update SET c=c+1 WHERE id=1;» >> test.sql;

а в этой конструкции он создаст запрос длиной в 400 килобайт. т.е. сначала этот запрос компилируется (к слову сказать, что компиляция запроса - очень дорогая операция, поэтому и придумали параметризированные запросы).

попробуй для начала выполнить свой запрос не через time, а просто внутри psql, посмотреть визуально насколько быстрее станет, дабы понять, аффектит ли тут роллбек (или у тебя там автокоммит?)

Deleted ()

Тот же тест но при fsync = off отрабатывает за полсекунды. Но это не решение.

Сделай периодический fsync (раз в неск.секунд) и реплика рядом и streaming replication на неё.

Вопрос: подскажите пожалуйста как ускорить UPDATE в Postgres?

UPDATE test_update SET c=c+10000 WHERE id=1;
shahid ★★★★★ ()
Ответ на: комментарий от shahid

UPDATE test_update SET c=c+10000 WHERE id=1;

весьма тонко )))))))

Deleted ()
Ответ на: комментарий от dnf83

Спасибо тебе добрый человек. Я slowpoke) Самое смешное что я эту мысль думал, но отбросил. Обернул - выполняется теперь за полторы секунды. Может еще что по тюнингу конфига подскажешь, про bgwriter'ы всякие

quest ★★★★ ()
Ответ на: комментарий от Deleted

нет, в postgres autocommit, из файла комманды читаются по одной сразу выполняются, rollback нет. Более того до этого я уже написал тест на c++ который открывает соединение и все меряет - результаты те-же

quest ★★★★ ()
Ответ на: комментарий от shahid

Пробывал играть с настройками bgwriter пока без результата. Оборачивание в транкцию ускорило радикально.

quest ★★★★ ()
Ответ на: комментарий от quest

Оборачивание в транкцию ускорило радикально.

На большой базе надо за расходом памяти следить. Там свои лимиты есть. При апдейте одной и той же ячейки лимиты, скорее всего, не досягаемы.

shahid ★★★★★ ()
Ответ на: комментарий от shahid

В реальности столбец то как в примере один, но строки конечно разные и их сотни тысяч

quest ★★★★ ()
Последнее исправление: quest (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.