【发布时间】:2015-07-11 22:34:05
【问题描述】:
我在 PostgreSQL 表中存储双精度的大型向量(140 万个值)。该表的创建语句如下。
CREATE TABLE analysis.expression
(
celfile_name character varying NOT NULL,
core double precision[],
extended double precision[],
"full" double precision[],
probeset double precision[],
CONSTRAINT expression_pkey PRIMARY KEY (celfile_name)
)
WITH (
OIDS=FALSE
);
ALTER TABLE analysis.expression ALTER COLUMN core SET STORAGE EXTERNAL;
ALTER TABLE analysis.expression ALTER COLUMN extended SET STORAGE EXTERNAL;
ALTER TABLE analysis.expression ALTER COLUMN "full" SET STORAGE EXTERNAL;
ALTER TABLE analysis.expression ALTER COLUMN probeset SET STORAGE EXTERNAL;
此表中的每个条目仅写入一次,并且可能在随机索引处读取多次。 PostgreSQL doesn't seem to scale terribly well for lookups as the vector length grows even with STORAGE set to EXTERNAL (O(n))。这使得查询如下,我们在数组中选择了许多单独的值,非常非常慢(分钟 - 小时)。
SELECT probeset[2], probeset[15], probeset[102], probeset[1007], probeset[10033], probeset[200101], probeset[1004000] FROM expression LIMIT 1000;
如果有足够多的单个索引被拉取,它甚至可能比拉取整个数组还要慢。
有什么方法可以使此类查询更快?
编辑
- 我使用的是 PostgreSQL 9.3。
-
我正在运行的所有查询可能都是简单的选择
SELECT probeset[2], probeset[15], probeset[102], probeset[1007], probeset[10033], probeset[200101], probeset[1004000] FROM expression JOIN samples s USING (celfile_name) WHERE s.study = 'x';在一种情况下,这些查询的结果是通过预测模型提供的。预测概率被存储回另一个表的数据库中。在其他情况下,从数组中提取选择项目以进行下游分析。
目前最长的单个数组是 140 万个,其他较短,最小的为 22000 个,平均长度约为 100000 个。
- 理想情况下,我会将数组数据存储为一个宽表,但是如果我们想要提取一个 140 万个条目,那么长表(即具有 celfile_name、索引、值的行)比 PostgreSQL 数组慢得多来自数据库的数据的完整数组。我们这样做是为了在对完整数据集进行分析时加载下游数据存储。
【问题讨论】:
-
我怀疑 Postgres 在对其进行任何操作之前需要读取整个数组。最好将值存储为表中的行,即使表表示更大。
-
您实际上不在 PostgreSQL 中存储大型数组,您只是存储对外部存储的引用。除非您在查询中使用数组中的数据将其与其他关系中的数据相结合,否则 PostgreSQL 的使用效率将不高。您如何使用 PostgreSQL 中的数据?您能否详细说明数组中的数据代表什么(例如时间序列?)以及四个数组之间的关系(f.i.每个数组中相同索引处的数据是否相关?)?所有四个数组的值都是 1.4M 长还是聚合大小?
-
对于性能问题来说,提供正在使用的 Postgres 版本应该是显而易见的。无需事先询问。
-
@GordonLinoff - 我编辑了这个问题来解释为什么将值存储在 PostgreSQL 表中是不可行的。
-
@Patrick - 我更新了这个问题,更深入地了解了将要运行的其他查询。简而言之,每个数组的长度可以非常长,最长的单个数组是 140 万个项目。跨数组的相同索引不相关。
标签: sql arrays postgresql bigdata postgresql-performance