Postgres и 1000 множественных звонков - PullRequest
0 голосов
/ 08 мая 2020

У меня есть DB PostgresSql Server v. 11.7, который на 100% используется только для локальной разработки. Аппаратное обеспечение: 16-ядерный ЦП, 112 ГБ памяти, 3 ТБ SSD m.2 (он работает под управлением Ubuntu 18.04 - но я получаю примерно такую ​​же скорость на моем ноутбуке windows 10, когда я запускаю точно такой же запрос локально).

БД содержит ~ 1500 таблиц БД (такой же структуры). Каждый вызов БД настраивается и указывает c, поэтому здесь нечего кешировать. С NodeJS я выполняю много одновременных вызовов (через await Promise.all (все 1000 обещаний)), а затем делаю много разных вычислений.

В настоящее время моя статистика выглядит так (максимальное соединение установлено на по умолчанию 100):

1 вызов ~ 100 мс

1.000 вызовов ~ 15 000 мс (15 мс / вызов)

Я пытался изменить различные настройки PostgreSQL. Например, чтобы изменить максимальное количество подключений на 1.000, но, похоже, ничто не помогает оптимизировать производительность (и да, я не забываю перезапускать службу PostgreSql каждый раз, когда вношу изменения).

Как мне сделать выполнение 1.000 одновременных вызовов как можно быстрее? Следует ли мне подумать о том, чтобы скопировать все необходимые данные в другую базу данных в памяти, такую ​​как Redis?

Таблица БД выглядит так:

CREATE TABLE public.my_table1 (
    id int8 NOT NULL GENERATED ALWAYS AS IDENTITY,
    tradeid int8 NOT NULL,
    matchdate timestamptz NULL,
    price float8 NOT NULL,
    "size" float8 NOT NULL,
    issell bool NOT NULL,
    CONSTRAINT my_table1_pkey PRIMARY KEY (id)
);
CREATE INDEX my_table1_matchdate_idx ON public.my_table1 USING btree (matchdate);
CREATE UNIQUE INDEX my_table1_tradeid_idx ON public.my_table1 USING btree (tradeid);

Простой тестовый запрос - получить 30 минут данные между двумя временными метками:

select * from my_table1 where '2020-01-01 00:00' <= matchdate AND matchdate < '2020-01-01 00:30'

total_size_incl_toast_and_indexes   21 GB total table size -->  143 bytes/row
live_rows_in_text_representation    13 GB total table size -->  89  bytes/row

Мой NodeJS код выглядит так:

const startTime = new Date();
let allDBcalls = [];
let totalRawTrades = 0;

(async () => {
    for(let i = 0; i < 1000; i++){
        allDBcalls.push(selectQuery.getTradesBetweenDates(tickers, new Date('2020-01-01 00:00'), new Date('2020-01-01 00:30')).then(function (rawTradesPerTicker) {
            totalRawTrades += rawTradesPerTicker["data"].length;
        }));
    }
    await Promise.all(allDBcalls);
    _wl.info(`Fetched ${totalRawTrades} raw-trades in ${new Date().getTime() - startTime} ms!!`);
})();

Я только что попытался запустить EXPLAIN - 4 раза по запросу:

EXPLAIN (ANALYZE,BUFFERS) SELECT * FROM public.my_table1 where '2020-01-01 00:00' <= matchdate and matchdate < '2020-01-01 00:30';



Index Scan using my_table1_matchdate_idx on my_table1  (cost=0.57..179.09 rows=1852 width=41) (actual time=0.024..0.555 rows=3013 loops=1)
  Index Cond: (('2020-01-01 00:00:00+04'::timestamp with time zone <= matchdate) AND (matchdate < '2020-01-01 00:30:00+04'::timestamp with time zone))
  Buffers: shared hit=41
Planning Time: 0.096 ms
Execution Time: 0.634 ms

Index Scan using my_table1_matchdate_idx on my_table1  (cost=0.57..179.09 rows=1852 width=41) (actual time=0.018..0.305 rows=3013 loops=1)
  Index Cond: (('2020-01-01 00:00:00+04'::timestamp with time zone <= matchdate) AND (matchdate < '2020-01-01 00:30:00+04'::timestamp with time zone))
  Buffers: shared hit=41
Planning Time: 0.170 ms
Execution Time: 0.374 ms

Index Scan using my_table1_matchdate_idx on my_table1  (cost=0.57..179.09 rows=1852 width=41) (actual time=0.020..0.351 rows=3013 loops=1)
  Index Cond: (('2020-01-01 00:00:00+04'::timestamp with time zone <= matchdate) AND (matchdate < '2020-01-01 00:30:00+04'::timestamp with time zone))
  Buffers: shared hit=41
Planning Time: 0.097 ms
Execution Time: 0.428 ms

Index Scan using my_table1_matchdate_idx on my_table1  (cost=0.57..179.09 rows=1852 width=41) (actual time=0.016..0.482 rows=3013 loops=1)
  Index Cond: (('2020-01-01 00:00:00+04'::timestamp with time zone <= matchdate) AND (matchdate < '2020-01-01 00:30:00+04'::timestamp with time zone))
  Buffers: shared hit=41
Planning Time: 0.077 ms
Execution Time: 0.586 ms
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...