我有一个类似下面的postgresql表。
CREATE TABLE "user" (
"id" integer NOT NULL,
"hash" char(40) NOT NULL,
"username" char(255) NOT NULL,
PRIMARY KEY ("id"),
UNIQUE ("hash"));然而,由于哈希是40个字母,我想做一个如下所示的函数索引,以减少内存需求。
CREATE INDEX CONCURRENTLY on user (substr(hash, 0, 20))这样做是可以的,还是只会生成另一个无用的索引?如何确保唯一索引仅索引散列中前20个字符?
谢谢。
发布于 2016-08-16 13:44:15
如果你需要散列是唯一的,你必须对整个事情有一个唯一的索引。否则,您将得到仅在最后20个字符中不同的散列的唯一违规。
您可以在左侧的20个字符上创建一个非唯一索引,如您所示:
CREATE INDEX on user (left(hash, 20))但它可能没有什么有用的目的。当您将其声明为UNIQUE约束时,PostgreSQL将自动为整个40个字符的散列创建唯一索引。如果不删除约束,则无法删除此索引。因此,如果您想强制使用散列的唯一性,则必须使用完整大小的索引。鉴于此,函数索引不太可能有太多好处。即使在像这样的查询中:
SELECT ...
FROM "user"
WHERE left(hash, 20) = left($1, 20) AND hash = $1 您可能认为使用较小的索引首先进行快速检查可以节省时间,但实际上,PostgreSQL很可能会忽略函数索引,而更喜欢完整的索引,因为它更具选择性。
我不完全清楚您想要实现什么,但是如果它在执行部分索引或函数索引来实现唯一约束,那么您就不能这样做。
另外,将hash存储为bytea并使用索引表达式left(hash, 20)。或者可能是10,如果您当前存储为每个字节2个字符的十六进制表示。
https://stackoverflow.com/questions/38966186
复制相似问题