Как хранить 300M записей в Postgresql для выполнения запросов эффективности - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть следующая таблица:

CREATE TABLE public.shop_prices
(
    shop_name text COLLATE pg_catalog."default",
    product text COLLATE pg_catalog."default",
    product_category text COLLATE pg_catalog."default",
    price text COLLATE pg_catalog."default"
)

и для этой таблицы у меня есть набор данных за 18 месяцев. В каждом файле около 15 миллионов записей. У меня есть некоторый анализ, например, в каком месяце магазин увеличил или уменьшил свою цену. Я импортировал два месяца в таблицу и запустил следующий запрос, чтобы проверить:

select shop, product from shop_prices group by shop, product limit 10

Я ждал более 5 минут, но никакого результата и ответа не было. Это было все еще на работе. Как лучше всего хранить эти наборы данных и выполнять запросы эффективности? Это хорошая идея, если я создаю для каждого набора данных отдельные таблицы?

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Используя explain analyze select shop_name, product from shop_prices group by shop, product limit 10, вы можете увидеть, как Postgres планирует и выполняет запрос и сколько времени занимает выполнение. Вы увидите, что необходимо прочитать всю таблицу (с учетом трудоемких операций чтения с диска), а затем отсортировать ее в памяти - которую, вероятно, необходимо будет кэшировать на диске, прежде чем возвращать результаты. При следующем запуске вы обнаружите, что тот же запрос очень быстр, если число комбинаций shop_name + product очень ограничено и, следовательно, сохраняется в pg_stats после этого анализа объяснения. Дело в том, что такой простой запрос может быть обманчивым.

Вы ускорите выполнение, создав индекс по столбцам, которые вы используете (create index shop_prices_shop_prod_idx on public.shop_prices(shop_name,product)).

Вам определенно следует изменить Если вы планируете делать какие-либо числовые расчеты, укажите в столбце Price значение Numberri c (или float / float8).

С учетом всего этого, я подозреваю, что эта таблица не является той, которую вы будете использовать, поскольку она У вас нет отметки времени для сравнения цен между месяцами.

Я предлагаю вам завершить разработку таблицы и порассуждать об индексах для повышения производительности. Возможно, вы даже захотите рассмотреть разбиение таблиц https://www.postgresql.org/docs/current/ddl-partitioning.html

Вероятно, вы будете выполнять все виды запросов к этим данным, поэтому не существует простого решения для всех них.

Во что бы то ни стало верните, возможно, более конкретные c вопросы с полным описанием таблицы и выводом из оператора объяснения анализа для запросов, которые вы пробуете, и получите полезные советы.

С уважением,
Bjarni

1 голос
/ 14 февраля 2020

Какая у вас PostgreSQL версия? Сначала опечатка: столбец shop должен быть shop_name. Во-вторых, ваш запрос выглядит странно, поскольку в нем есть только предложение LIMIT без каких-либо предложений ORDER BY или WHERE: вы действительно хотите иметь «случайные» строки для этого запроса?

Можете ли вы попытаться опубликовать вывод EXPLAIN для SQL оператор:

explain select shop_name, product from shop_prices group by shop_name, product limit 10;

Можете ли вы также проверить, была ли рассчитана какая-либо статистика для этой таблицы с помощью:

select * from pg_stats where tablename='shop_prices';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...