postgreOptimising使用SQLAlchemy过滤多个SQL计数子查询



我正在尝试将原始postgresql转换为使用计数和过滤器的sqlalchemy

SELECT
(
SELECT
COUNT(user_model.uuid)
FILTER ( WHERE  email_vector @@ parse_websearch('search term'))
) AS email_vector,
(
SELECT
COUNT(user_model.uuid)
FILTER ( WHERE  first_name_vector @@ parse_websearch('search term'))
) AS first_name_vector,
FROM 
user_model
WHERE  
(user_model.uuid = '20d7c90d-ebfa-4b04-9ee7-4fdedabc6c0b' AND all_vectors @@  parse_websearch('search term')  )

这工作得很好,非常快(低于100ms -即使过滤20个字段)

我把sqlalchemy写成(简化)

search_query = []
search_vectors = [ email_vector, first_name_vector]
search_vector_names = [ 'email_vector', 'first_name_vector' ] 
for search_vector, search_vector_name in zip(search_vectors, search_vector_names):
search_query.append(sa.sql.select(
sa.func.count(user_model.uuid)) 
.filter(search_vector.op('@@') 
(sa.func.parse_websearch(search_term))) 
.label(search_vector_name)
)
base_query = db.session.query(*search_query)
base_query = base_query.filter(user_model.uuid==user_uuid)
base_query = query.filter(search_vector.op('@@')(sa.func.parse_websearch(search_term))

生成以下SQL

SELECT (
SELECT count(user_model.uuid) AS count_1
FROM user_model
WHERE user_model.email_vector @@ parse_websearch(%(parse_websearch_1)s)) AS email_vector, 
(SELECT count(user_model.uuid) AS count_2
FROM user_model
WHERE user_model.first_name_vector @@ parse_websearch(%(parse_websearch_2)s)) AS first_name_vector,

WHERE user_model.uuid = %(uuid_1)s AND (user_model.all_vectors @@ parse_websearch(%(parse_websearch_30)s)) 

这可以工作,但相当慢(+1秒)。我不知道为什么这么慢,也不知道如何对子查询进行过滤查询。

我怀疑COUNT正在对SQL使用最终where条件过滤结果的每个子查询执行,但我不完全确定,我在sqlalchemy文档中找不到任何对filter的引用(我认为它是CASE的简写?)我试过将.filter(user_model.uuid==uuid)添加到COUNT SQL,但它仍然很慢。

有谁能告诉我我错过了什么吗?

我最终使用了CASE

case_stmt = sa.case(
[
(
full_text_search_vector.op('@@') 
(sa.func.parse_websearch(last_search_term)),1
)
]
).label(col_name)
query.append(case_stmt)

base_query = db.session.query(*query)

最新更新