我有一个棘手的问题,试图找到一种有效的方法来订购一组包含大量(约 500 万)索引数据点的对象(约 1000 行)。就我而言,我需要一个允许我按特定数据点对表进行排序的查询。每个数据点都是一个 16 位无符号整数。
我目前正在通过使用一个大数组来解决这个问题:
对象表:
id serial NOT NULL,
category_id integer,
description text,
name character varying(255),
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
data integer[],
要点索引:
CREATE INDEX object_rdtree_idx
ON object
USING gist
(data gist__intbig_ops)
当我进行选择查询时,当前未使用此索引,而且我不确定它是否会有所帮助。
每天数组字段都会更新一组新的约 500 万个值
我有一个网络服务器,它需要列出按特定数据点的值排序的所有对象:
示例查询:
SELECT name, data[3916863] as weight FROM object ORDER BY weight DESC
目前,执行此查询大约需要 2.5 秒。
问: 有没有更好的方法?我很高兴插入端在后台发生时很慢,但我需要选择查询尽可能快。这么说,插入需要多长时间是有限制的。
我已经考虑创建一个查找表,其中每个值都有自己的行 - 但我不确定这种方法会如何影响插入/查找时间,我怀疑输入 1000 多条记录,其中约 500 万个数据点作为单独的行会太慢了。
目前插入一行需要大约 30 秒,这目前是可以接受的。
最终,我仍在寻找基本问题的可扩展解决方案,但现在我需要这个解决方案才能工作,所以这个解决方案不需要进一步扩大规模。
更新: 我错误地认为拥有一个巨大的表而不是一个数组,而插入时间大大增加,查询时间减少到只有几毫秒。
我现在正在更改我的生成算法,以仅在它非零并且从以前的更新更改时才保存一个数据。这将插入减少到仅需要几秒钟的几十万个值。
新表:
CREATE TABLE data
(
object_id integer,
data_index integer,
value integer,
)
CREATE INDEX index_data_on_data_index
ON data
USING btree
("data_index");
新查询:
SELECT name, coalesce(value,0) as weight FROM objects LEFT OUTER JOIN data on data.object_id = objects.id AND data_index = 7731363 ORDER BY weight DESC
插入时间:15,000 条记录/秒
查询时间:17ms