powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Задержка при выполнении селекта по индексу
20 сообщений из 20, страница 1 из 1
Задержка при выполнении селекта по индексу
    #39162125
nateless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Приветствую,

Решили перевести проект на PostgreSQL но столкнулись с рандомными задержками, к примеру таблица outputs

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
                                               Table "public.outputs"
  Column   |   Type   |                      Modifiers                       | Storage  | Stats target | Description
-----------+----------+------------------------------------------------------+----------+--------------+-------------
 id        | integer  | not null default nextval('outputs_id_seq'::regclass) | plain    |              |
 trx_id    | integer  |                                                      | plain    |              |
 addresses | bigint[] | default '{}'::bigint[]                               | extended |              |
 position  | integer  |                                                      | plain    |              |
 amount    | bigint   | default 0                                            | plain    |              |
 spent     | boolean  | default false                                        | plain    |              |
Indexes:
    "outputs_pkey" PRIMARY KEY, btree (id)
    "index_outputs_on_addresses" btree (addresses)
    "index_outputs_on_trx_id" btree (trx_id)
    "index_outputs_on_trx_id_and_position" btree (trx_id, "position")



При первом запросе без кеша занимает около 12мс:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
prometheus=> explain analyze SELECT  "outputs".* FROM "outputs" WHERE "outputs"."trx_id" = 10212713 AND "outputs"."position" = 0 LIMIT 1;
                                                                 QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.56..0.98 rows=1 width=50) (actual time=12.096..12.096 rows=1 loops=1)
   ->  Index Scan using index_outputs_on_trx_id on outputs  (cost=0.56..17.91 rows=42 width=50) (actual time=12.096..12.096 rows=1 loops=1)
         Index Cond: (trx_id = 10212713)
         Filter: ("position" = 0)
         Rows Removed by Filter: 1
 Planning time: 0.045 ms
 Execution time: 12.107 ms
(7 rows)



В таблице около 35M записей, прогнозируем рост до 100М

Так же очень долгий insert bulk записей, к примеру запрос INSERT INTO "outputs" ("trx_id", "addresses", "position", "amount") VALUES (15341844, '{813298}', 0, 4999500000), (15341844, '{11407753}', 1, 1001313) returning id; может занимать до 20ms, но в большинстве случаев исполняется за 0.5-1ms


vacuum\analyze делали.


Сервер 32GB RAM, конфиг:
synchronous_commit = off - временно отключили его что бы оптимизировать импорт
effective_cache_size = 23040MB
work_mem = 78643kB
maintenance_work_mem = 1920MB
checkpoint_segments = 32
checkpoint_completion_target = 0.7
wal_buffers = 16MB
default_statistics_target = 100
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162142
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
natelessТак же очень долгий insert bulk записей, к примеру запрос INSERT INTO "outputs" ("trx_id", "addresses", "position", "amount") VALUES (15341844, '{813298}', 0, 4999500000), (15341844, '{11407753}', 1, 1001313) returning id; может занимать до 20ms , но в большинстве случаев исполняется за 0.5-1ms


20 ms -- это же нормально, чего жалуешься?
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162154
nateless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv20 ms -- это же нормально, чего жалуешься?
около 80% всех инсертов укладываются меньше чем в 1ms. Для нас это критично.
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162206
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nateless,

10-20ms - порядок времени задержки обращения к диску так что это нормальное поведение.
Надо гарантированно быстрее - используйте SSD, а них задержки на пару порядков ниже будут.

PS: а сколько у вас shared_buffers?

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162222
nateless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguknateless,

10-20ms - порядок времени задержки обращения к диску так что это нормальное поведение.
Надо гарантированно быстрее - используйте SSD, а них задержки на пару порядков ниже будут.

PS: а сколько у вас shared_buffers?

--
Maxim Boguk
www.postgresql-consulting.ru

shared_buffers = 8GB

На SSD видим примерно такие-же спайки при похожей конфигурации правда БД только 70% от основной, хотя на новом сервере памяти 64GB и настройки соотвественные.
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162229
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
natelessMaxim Boguknateless,

10-20ms - порядок времени задержки обращения к диску так что это нормальное поведение.
Надо гарантированно быстрее - используйте SSD, а них задержки на пару порядков ниже будут.

PS: а сколько у вас shared_buffers?

--
Maxim Boguk
www.postgresql-consulting.ru

shared_buffers = 8GB

На SSD видим примерно такие-же спайки при похожей конфигурации правда БД только 70% от основной, хотя на новом сервере памяти 64GB и настройки соотвественные.

Плохой ssd значит. Нормальный SSD Intel s3710 (в крайнес случае s3610 или s3510).
полезно включать track_io_timing
и делать explain (analyze, costs, buffers, timing) запрос
чтобы понимать что происходит.

Такие пики время от времени это только дисковый IO.

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162254
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
natelessMasterZiv20 ms -- это же нормально, чего жалуешься?
около 80% всех инсертов укладываются меньше чем в 1ms. Для нас это критично.

Это не может быть критично.
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162266
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
natelessMasterZiv20 ms -- это же нормально, чего жалуешься?
около 80% всех инсертов укладываются меньше чем в 1ms. Для нас это критично.

Делайте асинхронную вставку/буферизацию. Т.е. пишите в файл или в быструю очередь а уж из нее скидывайте в базу.
Но вообще 20ms в 1 случае из 100-1000 не должно быть проблемой.

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162275
nateless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguknatelessпропущено...

около 80% всех инсертов укладываются меньше чем в 1ms. Для нас это критично.

Делайте асинхронную вставку/буферизацию. Т.е. пишите в файл или в быструю очередь а уж из нее скидывайте в базу.
Но вообще 20ms в 1 случае из 100-1000 не должно быть проблемой.

--
Maxim Boguk
www.postgresql-consulting.ru

Не можем. Мы импортируем БД blockchain, каждый блок состоит из двух тысяч транзакций, каждая транзакция состоит из входов ( предыдущие выходы ) и выходов, которых в транзакции может быть от 1 до нескольких тысяч. Сейчас каждый блок импортируется в среднем за 60 секунд и это примерно 60% завершено, дальше будет дольше. Каждый блок идет в транзакцию что бы откатить в случае ошибки или остановки. В эту транзакцию укладываются все данные их десятки тысяч записей + апдейты старых. По сколько данные зависят друг от друга необходимо добавлять к приеру транзакцию перед входами и выходами так как они ссылаются на id. необходимо помечать выхода как использованные с каждой транзакцией, и еще много чего.

Поэтому спайки в 20 мс на 1000 транзакций дают задержку в 10-20 секунд на блок, а блоков 400 тысяч. При текущей скорости импорта это займет почти месяц, что ну ни в какие ворота :) А если ошибка в коде и нужно будет реимпортнуть БД то можно застрелиться.
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162300
Павел Лузанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nateless,

Из общих соображений.
Индексы по trx_id точно нужны оба?
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162310
nateless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Павел Лузановnateless,

Из общих соображений.
Индексы по trx_id точно нужны оба?

Да спасибо, я уже сегодня понял что нам надо иcключить несколько индексов вообще пока идет импорт, так как они влияют на скорость записи, а сипользуются уже на вебморде после импорта.
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162354
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
natelesssynchronous_commit = off - временно отключили его что бы оптимизировать импорт
work_mem = 78643kB
checkpoint_segments = 32
checkpoint_completion_target = 0.7
Если вы много пишете в базу, то имеет смысл добавить сегментов, до 128 для начала. И c_c_t поднять до 0.85-0.9.

Если это разовая операция и надо быстрее, то может `fsync = off`? Тем более, что уже `synchronous_commit = off`.

И `work_mem` большой, при умолчательных 100 соединениях вы отдаете 78GB, которых нету. Зачем так много?


Что у вас в `/etc/sysctl.conf` на тему `vm.%`?
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162405
nateless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovnatelesssynchronous_commit = off - временно отключили его что бы оптимизировать импорт
work_mem = 78643kB
checkpoint_segments = 32
checkpoint_completion_target = 0.7
Если вы много пишете в базу, то имеет смысл добавить сегментов, до 128 для начала. И c_c_t поднять до 0.85-0.9.

Если это разовая операция и надо быстрее, то может `fsync = off`? Тем более, что уже `synchronous_commit = off`.

И `work_mem` большой, при умолчательных 100 соединениях вы отдаете 78GB, которых нету. Зачем так много?


Что у вас в `/etc/sysctl.conf` на тему `vm.%`?

Спасибо, поробуем с этими настройками сегодня. По факту 100 соединений нет, на импорт идет один коннект. В основном пишем, то что пишем потом стараемся сразу в redis класть что бы дергать от туда потом.

sysctl.conf поправили слегка:
kernel.shmmax = 16797089792
kernel.shmall = 4100852
vm.swappiness = 10
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162464
Sergei.Agalakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стандартно на массивный начальный импорт отключают все индексы кроме тех, которые могут быть использованы самим импортом.
Как вам уже сказали, вы при массивном импорте упираетесь в IO на дисковой системе. Как бы вы не игрались с кэшем файловой системы, контроллера массива и т.д. в долговременном плане вы упираетесь в скорость записи на диск. Следовательно, писать надо абсолютный минимум, а дисковая подсистема должна быть максимально быстрой. На сегодняшний день самые быстрые диски за вменяемые деньги будут SSD.
К уже упомянутым настройкам можно добавить wal_level = minimum если меняли на другое.
После импорта поменяете настройки базы, создадите индексы, да и данные можно будет скопировать на более медленные и дешевые носители.
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39162644
Lonepsycho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nateless,

если то что импортировалось хранить ненадо, а данные только както обрабатываются и загружается новая порция, можно посмотреть в сторону UNLOGGED TABLE. так ещё секонимите IO на WAL.
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39163582
nateless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Удалось частично ускорить выполнение, но все равно появляются рандомные спайки, к примеру этот запрос выполнялся 16!! секунд в первый раз:

Код: sql
1.
UPDATE "outputs" SET "spent" = 't' WHERE "outputs"."id" IN (37608707,....примерно 600 ид);





Код: sql
1.
2.
3.
4.
5.
6.
7.
--------------------------------------------------------------------------------------------------------------------------------------------
 Update on outputs  (cost=1.28..3016.85 rows=577 width=55) (actual time=14.439..14.439 rows=0 loops=1)
   ->  Index Scan using outputs_pkey on outputs  (cost=1.28..3016.85 rows=577 width=55) (actual time=0.091..11.570 rows=577 loops=1)
         Index Cond: (id = ANY ('{37608707,40562950,...,49040473}'::integer[]))
 Planning time: 0.692 ms
 Execution time: 14.537 ms
(5 rows)
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39163646
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nateless,

Сложно сказать. Может холодная часть как индекса, так и таблицы. Может был чекпойнт.

Что показывает `sysctl -a|egrep '^vm.dirty'`? Если там большие значения (особенно в `%_ratio`, что есть проценты от виртуальной памяти), то ядро будет долго копить грязные страницы (до указанных значений) и потом разом сбрасывать на диск (блокирующая операция, если объем превышает кэш диска). Если вы отключили `fsync`, то это вполне возможно — надо понизить параметры.

Вы саму систему мониторите (IO, VM, CPU)? Было бы полезно видеть что происходит на уровне ОС в такие моменты.

Для проблемных запросов приводите вывод `EXPLAIN (analyze, buffers)` — это поможет лучше понять сколько буферов обрабатывается запросом.
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39163663
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
natelessУдалось частично ускорить выполнение, но все равно появляются рандомные спайки, к примеру этот запрос выполнялся 16!! секунд в первый раз:

Код: sql
1.
UPDATE "outputs" SET "spent" = 't' WHERE "outputs"."id" IN (37608707,....примерно 600 ид);





Код: sql
1.
2.
3.
4.
5.
6.
7.
--------------------------------------------------------------------------------------------------------------------------------------------
 Update on outputs  (cost=1.28..3016.85 rows=577 width=55) (actual time=14.439..14.439 rows=0 loops=1)
   ->  Index Scan using outputs_pkey on outputs  (cost=1.28..3016.85 rows=577 width=55) (actual time=0.091..11.570 rows=577 loops=1)
         Index Cond: (id = ANY ('{37608707,40562950,...,49040473}'::integer[]))
 Planning time: 0.692 ms
 Execution time: 14.537 ms
(5 rows)

600 произвольных доступов. это если у вас индексы не опухшие. Т.е *4 -- около 2400/в минуту. Только на чтение.

но что--то подсказывает мне, что индексы у вас опухшие раз в 5--10. такое у меня предчувствие, судя по вашему коду. и вашему же времени.
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39163721
nateless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq600 произвольных доступов. это если у вас индексы не опухшие. Т.е *4 -- около 2400/в минуту. Только на чтение.

но что--то подсказывает мне, что индексы у вас опухшие раз в 5--10. такое у меня предчувствие, судя по вашему коду. и вашему же времени.

Что значит опухшие? Я просто еще не очень разбираюсь в PostgreSQL.

vyegorovnateless,

Сложно сказать. Может холодная часть как индекса, так и таблицы. Может был чекпойнт.

Что показывает `sysctl -a|egrep '^vm.dirty'`? Если там большие значения (особенно в `%_ratio`, что есть проценты от виртуальной памяти), то ядро будет долго копить грязные страницы (до указанных значений) и потом разом сбрасывать на диск (блокирующая операция, если объем превышает кэш диска). Если вы отключили `fsync`, то это вполне возможно — надо понизить параметры.

Вы саму систему мониторите (IO, VM, CPU)? Было бы полезно видеть что происходит на уровне ОС в такие моменты.

Для проблемных запросов приводите вывод `EXPLAIN (analyze, buffers)` — это поможет лучше понять сколько буферов обрабатывается запросом.

vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 10
vm.dirty_bytes = 0
vm.dirty_expire_centisecs = 3000
vm.dirty_ratio = 20
vm.dirty_writeback_centisecs = 500
vm.dirtytime_expire_seconds = 43200


Диск загружен на 60% примерно. fsync отключили. Потребление памяти очень низкое 10GB из 32GB. load average: 3.80. Слегка свапится около 800MB.
...
Рейтинг: 0 / 0
Задержка при выполнении селекта по индексу
    #39163863
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
natelessУдалось частично ускорить выполнение, но все равно появляются рандомные спайки, к примеру этот запрос выполнялся 16!! секунд в первый раз:

Код: sql
1.
UPDATE "outputs" SET "spent" = 't' WHERE "outputs"."id" IN (37608707,....примерно 600 ид);




[/src]

Первый раз - данные все не в памяти уже (т.е. холодные).
Смотрите... 600 ID это 600 раз считать страницы с индекса + 600 раз считать страницы с таблицы (и это в лучшем случае), вероятнее всего еще *2.
1200 IO на механическом НИЧЕМ другим не занятом диске выполняются за 10-20 секунд и быстрее вы это НИКАК не сделаете.
А по вашим словам у вас еще и диски заняты. А PostgreSQL тут собственно не причем он работает с той скоростью с которой ему диски данные отдают в таких случаях.

Быстрый (относительно) ответ по холодным данным возможен только на SSD где 1200IO операций можно за 0.1s отработать.

PS: альтернативное решение - выделить достаточно оперативки на сервере и достаточно shared buffers так чтобы база всегда целиком лежала в shared buffers базы (т.е. shared_buffers>database size). Но даже в такой ситуации после рестарта сервера будет много тормозов пока данные с дисков в память все попадут.
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Задержка при выполнении селекта по индексу
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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