所以,我已经使用 Postgres/sqlalchemy 进行全文搜索有一段时间了。没问题,但现在它开始变得很慢,因为表中的项目数量开始变多(例如 600k 项目,这需要大约 10 秒以上)。因此,决定研究一下杜松子酒的索引。
我能够正常创建索引。
问题是,它没有被使用(当我查看 pgAdmin 时进行了 0 次扫描),所以我想知道我做错了什么,或者我是否必须强制使用索引或其他东西。
索引之前的我的表(flask-sqlalchemy 语法):
class Parent_product(db.Model):
id = ....
name = db.Column(db.String)
我会像这样进行搜索(忽略旧的 sqlalchemy 语法):
query = db.session.query(Parent_product)
query = query.order_by(func.similarity(Parent_product.name, search_string).desc())
query = query.filter(func.similarity(Parent_product.name, search_string) > 0.1)
search_results = query.limit(5).all()
然后,我开始实验并在 Parent_product 类中添加了一个索引,如下所示:
__table_args__ = (
(
Index(
'ix_parent_product_name',
name,
postgresql_using="gin",
postgresql_ops={
'name': 'gin_trgm_ops',
}
)
),
)
工作正常,我可以看到索引已在数据库中构建,但如上所述,它没有在相似性查询中使用。
好吧,我想我明白了。显然,您需要使用所谓的运算符来让 postgres 使用您的索引。
func.similarity
不是运算符,这意味着我必须在搜索查询中将其交换出来,如下所示:
db.session.execute('SET pg_trgm.similarity_threshold = 0.1;')
query = db.session.query(Parent_product)
query = query.filter(Parent_product.name.op("%")(search))
query = query.order_by(Parent_product.name.op("%>")(search).desc())
现在我可以看到正在使用的索引。不太确定我在做什么,但它工作得很快。