如何在 Postgresql 中存储 300M 记录以 运行 效率查询

How to store 300M records in Postgresql to run efficiency queries

我关注table:

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"
)

为此 table 我有一个 18 个月的数据集。每个文件中大约有 15M 条记录。我必须进行一些分析,例如一家商店在哪个月提高或降低了价格。我在 table 和 运行 中输入了两个月的以下查询只是为了测试:

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

我等了5个多分钟,没有任何结果和回应。它仍在工作。存储这些数据集和 运行 效率查询的最佳方式是什么?如果我为每个数据集创建一个单独的 tables 是个好主意吗?

您的 PostgreSQL 版本是什么? 首先有一个错别字:专栏shop应该是shop_name。 其次,你的查询看起来很奇怪,因为它只有一个 LIMIT 子句,没有任何 ORDER BY 子句或 WHERE 子句:你真的想要这个查询有 "random" 行吗?

您能否尝试 post EXPLAIN SQL 语句的输出:

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

您还可以检查是否已针对此 table 计算了任何统计信息:

select * from pg_stats where tablename='shop_prices';

使用 explain analyze select shop_name, product from shop_prices group by shop, product limit 10 您可以看到 Postgres 如何计划和执行查询以及执行所花费的时间。您会看到它需要读取整个 table(耗时的磁盘读取),然后在内存中对其进行排序 - 在 return 计算结果之前,这可能需要缓存在磁盘上。在接下来的 运行 中,如果 shop_name+ 产品组合的数量非常有限并因此在解释分析后存储在 pg_stats 中,您可能会发现相同的查询非常快速。关键是像这样的简单查询可能具有欺骗性。

您可以通过在您正在使用的列上创建索引来加快执行速度 (create index shop_prices_shop_prod_idx on public.shop_prices(shop_name,product))。

如果您打算对其进行任何数值计算,您绝对应该将价格列类型更改为数字(或 float/float8)。

说了这么多,我怀疑这个 table 不是您要使用的,因为它没有任何时间戳来比较开始的月份之间的价格。

我建议您完成 table 设计并推测索引以提高性能。您甚至可能需要考虑 table 分区 https://www.postgresql.org/docs/current/ddl-partitioning.html

您可能会对这些数据进行各种查询,因此没有简单的解决方案。

一定要 return 提出可能更具体的问题,并提供完整的 table 描述以及您正在尝试的查询的解释分析语句的输出,并获得一些好的建议。

此致,
比亚尼