powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Интересный и важный момент обновления записи (помогите)
9 сообщений из 9, страница 1 из 1
Интересный и важный момент обновления записи (помогите)
    #39318307
VladimirDmitriev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. Помогите, пожалуйста, понять причину следующей особенности.
Есть таблица:
Код: plsql
1.
2.
3.
4.
5.
6.
CREATE TABLE app_test
(
  id numeric NOT NULL,
  curr_value numeric NOT NULL DEFAULT 0,
  CONSTRAINT app_test_pk PRIMARY KEY (id)
);


Заполненная случайными значениями:
Код: plsql
1.
INSERT INTO app_test SELECT generate_series(1, 100);


Есть "счетчик":
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE OR REPLACE FUNCTION app_get_next(counter_id numeric)
RETURNS numeric AS $$
  UPDATE app_test
  SET curr_value = curr_value + 1
  WHERE id = counter_id
  RETURNING curr_value
$$
LANGUAGE SQL;


Если добавлять значения случайным записям, мой компьютер отрабатывает в среднем за 3.0 сек.
Код: plsql
1.
SELECT app_get_next(floor(random()*100)::numeric) FROM generate_series(1, 30000);


Если обновлять значение определенной записи - за 22.5 (!) сек.
Код: plsql
1.
SELECT app_get_next(50) FROM generate_series(1, 30000);


В чем дело? Где загвоздка?


И следом второй вопрос. Если нужно большое количество независимых последовательностей (sequence), правильно ли ее реализовывать приведенным выше способом в одной таблице? Или блокировки будут сильно мешать, и лучше забыть на неудобство и реализовать их управление процедурно (присутствует логика управления и периодичность обнуления)?
-- "PostgreSQL 9.5.3, compiled by Visual C++ build 1600, 32-bit"
...
Рейтинг: 0 / 0
Интересный и важный момент обновления записи (помогите)
    #39318431
Author the new one
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VladimirDmitriev,

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

С последовательностями неправильно, для корректной реализации их вам потребуются автономные транзакции или особое умение клиента работать с ними. К слову сказать, а чем не устраивают штатные последовательности?
...
Рейтинг: 0 / 0
Интересный и важный момент обновления записи (помогите)
    #39318459
ОКТОГЕН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Author the new oneVladimirDmitriev,

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

С последовательностями неправильно, для корректной реализации их вам потребуются автономные транзакции или особое умение клиента работать с ними. К слову сказать, а чем не устраивают штатные последовательности?
Думаю, это надо для безразрывной нумерации записей.
Знаменитейший антипаттерн
...
Рейтинг: 0 / 0
Интересный и важный момент обновления записи (помогите)
    #39318469
VladimirDmitriev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Author the new oneVladimirDmitriev,

Тормоза с обновлением единственной записи связаны с реализацией MVCC в PostgreSQL.

Спасибо. Можете пояснить немного подробнее? Хочется полного понимания.
...
Рейтинг: 0 / 0
Интересный и важный момент обновления записи (помогите)
    #39318474
VladimirDmitriev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ОКТОГЕН,

Вы правы. "Присутствует логика управления и периодичность обнуления".
...
Рейтинг: 0 / 0
Интересный и важный момент обновления записи (помогите)
    #39318476
VladimirDmitriev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ОКТОГЕН, Вы правы. "Присутствует логика управления и периодичность обнуления".
...
Рейтинг: 0 / 0
Интересный и важный момент обновления записи (помогите)
    #39318495
ОКТОГЕН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VladimirDmitrievОКТОГЕН, Вы правы. "Присутствует логика управления и периодичность обнуления".
Как вы собираетесь поддерживать актуальные номера во всех других ссылках и внутри всех документах? Да ещё при конкурентном доступе?
Зачем вам этот нереальный геморрой?
...
Рейтинг: 0 / 0
Интересный и важный момент обновления записи (помогите)
    #39318716
VladimirDmitriev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ОКТОГЕН,
Геморрой не мой. Как раз хочу излечить.
Спасибо.
...
Рейтинг: 0 / 0
Интересный и важный момент обновления записи (помогите)
    #39319097
PgSQLanonymous3
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VladimirDmitrievЕсть таблица:
Код: plsql
1.
2.
3.
4.
5.
6.
CREATE TABLE app_test
(
  id numeric NOT NULL,
  curr_value numeric NOT NULL DEFAULT 0,
  CONSTRAINT app_test_pk PRIMARY KEY (id)
);



А почему numeric-и, а не int-ы, например?
Я начну со второго вопроса:
VladimirDmitrievЕсли нужно большое количество независимых последовательностей (sequence),
правильно ли ее реализовывать приведенным выше способом в одной таблице?

Да, правильно. Кстати, [вены] правильно резать вдоль. ;)
Это я к тому, что с неразрывными последовательностями (gapless sequence) стоит
связываться только тогда, когда этого требует какой-нибудь закон,
да и тогда их обычно нужно одна-две, и используются они обычно
для номеров каких-нибудь документов.
VladimirDmitrievИли блокировки будут сильно мешать, и лучше забыть на неудобство и реализовать
их управление процедурно (присутствует логика управления и периодичность обнуления)?

Скорее всего, будут мешать, и с этим ничего не поделаешь --- для неразрывной
последовательности необходима "точка сериализации".
И, более того, т.к. полученное значение должно быть использовано в той же транзакции,
то все прочие, которым нужно значение этой последовательности, ждут её завершения.
Поэтому общая производительность будет в основном зависеть не от того,
насколько быстро генерируются эти значения, а от длительности конкурирующих транзакций.

VladimirDmitrievЕсли добавлять значения случайным записям, мой компьютер отрабатывает в среднем за 3.0 сек.
Код: plsql
1.
SELECT app_get_next(floor(random()*100)::numeric) FROM generate_series(1, 30000);


Если обновлять значение определенной записи - за 22.5 (!) сек.
Код: plsql
1.
SELECT app_get_next(50) FROM generate_series(1, 30000);


В чем дело? Где загвоздка?

Загвоздка в том, что если Вы таким образом пытаетесь получить ответ на второй
вопрос, Вы измеряете погоду на Марсе. ;) Во-первых, см. выше,
во-вторых, Вы же не собираетесь использовать это таким образом (т.е.
получать 30000 номеров в одной транзакции), зачем Вы это измеряете?
Если уж измерять, то как-то так (создаёте файлы с тестируемыми запросами,
используете их в pgbench):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
gapless.sql:
SELECT app_get_next(50);
gapless_random.sql:
app_get_next(floor(random()*100)::numeric);
---
Ну и потом:
pgbench -n -M prepared -T 60 -f gapless.sql yourdatabase
pgbench -n -M prepared -T 60 -f gapless_random.sql yourdatabase


И вот у меня, например, получается:
Код: sql
1.
2.
tps = 368.14
tps = 373.78


Хотя смысла в этом я (косвенно замерив, в основном, продолжительность COMMIT-а), опять-таки, не вижу. ;)

Если же Вас всё ещё интересует ответ на первый вопрос, то см.:
https://www.postgresql.org/docs/current/static/storage.html
и src/backend/access/heap/README.HOT в исходниках.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Интересный и важный момент обновления записи (помогите)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]