我正在尝试在Postgres 9.6数据库中添加包含UUID的GIN索引。从技术上讲,它是一个复合索引,来自btree_gin插件的复合GIN支持。
我尝试使用以下语句创建索引:
CREATE EXTENSION btree_gin;
CREATE INDEX ix_tsv ON text_information USING GIN (client_id, text_search_vector);
但我得到这个错误:
ERROR: data type uuid has no default operator class for access method "gin" HINT: You must specify an operator class for the index or define a default operator class for the data type.
client_id
是数据类型uuid
和text_search_vector
是tsvector
。我不认为复合/ btree_gin因子实际上是相关的,因为我在单独的client_id
上尝试创建索引时遇到同样的错误,但希望如果有一个解决方案,那么它将适用于复合索引也。
我找到了PostgreSQL GIN index on array of uuid,这似乎表明它应该是可能的(如果可以完成一个UUID阵列,那么肯定可以完成一个单独的UUID)。但是,那里的解决方案对我来说非常不透明 - 如何修改此解决方案以支持单个UUID并不是很明显。
我更喜欢一种不涉及将UUID转换为索引或另一列中的另一种类型的解决方案,因为我宁愿不必编写带有强制转换的专用查询(我们使用django ORM来生成查询atm)。
GIN索引是可能的。但不是在Postgres 11之前,它被添加了。 The release notes:
允许
btree_gin
索引bool
,bpchar
,name
和uuid
数据类型(Matheus Oliveira)
所以简单的解决方案就是升级到Postgres 11.This对你来说应该是个好消息:
2019年4月9日:Cloud SQL现在支持PostgreSQL版本11.1 Beta
或者,在许多情况下,您也可以使用GiST索引,而Postgres 10已经引入了GiST索引。 The release notes:
为
UUID
数据类型添加索引支持btree_gist(Paul Jungwirth)
有关:
如果两者都不是一个选项,那么您将回到您想要避免的内容:
将uuid转换为索引中的另一个类型
您可以在(一致!)text
表示上创建表达式索引,或者理论上,在bigint
派生的两个uuid
列上创建表达式索引。但第一个使得索引更大更慢,第二个使得复杂化更加复杂......
演员的语法很简单:uuid::text
。在索引表达式中,需要一组额外的括号。安装了附加模块btree_gin
:
CREATE INDEX ix_uuid_tsv ON text_information USING GIN ((client_id::uuid), tsv);
有关:
或者你可以从Postgres 11向后移植这个功能 - 如你在评论中提到的那样,这不是托管服务的选项,例如Google Cloud SQL for PostgreSQL。我几乎没有看到一个用例,其中一个人将足够熟练地实现backport,但不会升级到Postgres 11。