强制更新索引
Force index to be updated
我将所有权作为 "Project -> Ownership -> User" 关系处理,以下函数获取项目所有者的名称作为文本:
CREATE FUNCTION owners_as_text(projects) RETURNS TEXT AS $$
SELECT trim(both concat_ws(' ', screen_name, first_name, last_name)) FROM users
INNER JOIN ownerships ON users.id = ownerships.user_id
WHERE deleted_at IS NULL AND ownable_id = .id AND ownable_type = 'Project'
$$ LANGUAGE SQL IMMUTABLE SET search_path = public, pg_temp;
这随后用于构建忽略重音符号的索引:
CREATE INDEX index_projects_on_owners_as_text
ON projects
USING GIN(immutable_unaccent(owners_as_text(projects)) gin_trgm_ops)
更新项目时,也会更新此索引。然而,当例如所有者名称更改,该索引不会被触及,对吗?
在这种情况下,如何强制定期更新索引以赶上进度?
(REINDEX
不是一个选项,因为它是锁定的,如果写入操作同时发生,将导致死锁。)
这个想法是错误的假设,因为索引是建立在一个实际上不是不可变的函数之上的。对于文档:
IMMUTABLE indicates that the function cannot modify the database and always returns the same result when given the same argument values; that is, it does not do database lookups or otherwise use information not directly present in its argument list.
您现在面临的问题源于不正确的假设。
由于您通过说函数是 IMMUTABLE
而实际上是 STABLE
来欺骗 PostgreSQL,因此当数据库更改时索引损坏也就不足为奇了。
解决方法是不创建这样的索引。
最好不要使用该功能,而是将要搜索的表达式作为列的视图。然后可以优化使用视图的查询,可以使用immutable_unaccent(btrim(concat_ws(' ', screen_name, first_name, last_name)))
上的索引。
欺骗unaccent
的波动性可能是可以的...
我将所有权作为 "Project -> Ownership -> User" 关系处理,以下函数获取项目所有者的名称作为文本:
CREATE FUNCTION owners_as_text(projects) RETURNS TEXT AS $$
SELECT trim(both concat_ws(' ', screen_name, first_name, last_name)) FROM users
INNER JOIN ownerships ON users.id = ownerships.user_id
WHERE deleted_at IS NULL AND ownable_id = .id AND ownable_type = 'Project'
$$ LANGUAGE SQL IMMUTABLE SET search_path = public, pg_temp;
这随后用于构建忽略重音符号的索引:
CREATE INDEX index_projects_on_owners_as_text
ON projects
USING GIN(immutable_unaccent(owners_as_text(projects)) gin_trgm_ops)
更新项目时,也会更新此索引。然而,当例如所有者名称更改,该索引不会被触及,对吗?
在这种情况下,如何强制定期更新索引以赶上进度?
(REINDEX
不是一个选项,因为它是锁定的,如果写入操作同时发生,将导致死锁。)
这个想法是错误的假设,因为索引是建立在一个实际上不是不可变的函数之上的。对于文档:
IMMUTABLE indicates that the function cannot modify the database and always returns the same result when given the same argument values; that is, it does not do database lookups or otherwise use information not directly present in its argument list.
您现在面临的问题源于不正确的假设。
由于您通过说函数是 IMMUTABLE
而实际上是 STABLE
来欺骗 PostgreSQL,因此当数据库更改时索引损坏也就不足为奇了。
解决方法是不创建这样的索引。
最好不要使用该功能,而是将要搜索的表达式作为列的视图。然后可以优化使用视图的查询,可以使用immutable_unaccent(btrim(concat_ws(' ', screen_name, first_name, last_name)))
上的索引。
欺骗unaccent
的波动性可能是可以的...