关于Postgres中索引的优化,我有一个问题,我在网上找不到多少帮助,而且我自己也很难通过测试得到答案。
我有这张桌子
CREATE TABLE "public"."crawls" (
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
"parent_id" uuid,
"group_id" timestamp,
"url" varchar(2083) NOT NULL,
"done" boolean;
PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "parentid_groupid_url" ON "public"."urls" USING BTREE ("parent_id","group_id","url");它是一个URL存储库,用于计算每个父级和每个组唯一的URL的综合列表。我只需要在这个索引上精确匹配。这意味着,只要parent_id是不同的,group_id可以在同一时间拥有多次相同的URL。
这个表包含了数亿的URL,主要用于写,唯一的索引是去重复。
UPDATE crawls
SET
done = TRUE
WHERE
url = $1 AND
parent_id = $2 AND
group_id = $3
INSERT
INTO crawls (
url,
parent_id,
group_id
) VALUES
('long urls', uuid, date)
ON CONFLICT parentid_groupid_url DO NOTHING目前perf还可以,但可能更好,而且由于url列的存在,索引大小比表本身大。
,我想知道我怎样才能改进自己的尺寸和/或特权?(如果可能的话)
我考虑使用一个新列对URL进行散列(md5,sha1),并将其用于索引中,而不是URL,这样长度就一致、更小,而且对于Postgres来说可能更快,但我没有在这方面找到任何帮助。我不确定它是否有效,因为散列的“随机性”,而且我很难检验这个假设,因为它的大小和时间在我的产品上构建索引。
我在网上找到的参考文献:
谢谢,
发布于 2020-02-08 18:11:30
我考虑使用一个新列来散列(md5,sha1),并在索引中使用它而不是URL,这样长度就一致、更小,而且对于Postgres来说可能更快。
create index on crawls (parent_id,group_id,md5(url));这将自动执行唯一性(并禁止在整个URL上真正不同的md5冲突--但在没有恶意的情况下,发生这种冲突的可能性很小)。但是,它不会自动用于快速查找,您必须调整查询以允许使用它:
WHERE
md5(url) = md5($1) AND
parent_id = $2 AND
group_id = $3通过使用比十六进制更短的重新命名,可以节省更多的空间:
create index on crawls (parent_id,group_id,decode(md5(url),'hex'));但这将使它的使用更加繁琐。
我不确定它是否有效,因为散列的“随机性”
这完全取决于您的使用模式和数据分布。如果您通常使用相同的parent_id和group_id以及相邻的urls访问一系列记录,并且具有相同的parent_id和group_id的记录数量很大,那么哈希urls可能会降低缓存的效率。
,我很难检验这个假设,因为它的大小和建立指数的时间都在我的产品上。
没有测试环境就是双手被绑在背后。
https://stackoverflow.com/questions/60128328
复制相似问题