PostgreSQL优化包含CTE窗口函数的查询性能
这里,PostgreSQL优化包含CTE窗口函数的查询性能,sql,postgresql,common-table-expression,window-functions,jsonb,Sql,Postgresql,Common Table Expression,Window Functions,Jsonb,这里,便利设施类别和父路径列是JSONB列,其值分别为[“电视”、“空调”]和[“20000”、“20100”、“203”]。除此之外,其他列是正常的varchar和numeric类型。我有大约250万行,主键在id上,它被索引了。基本上,当rp.parent\u路径匹配多行时,初始CTE部分需要时间 样本数据集: WITH CTE AS ( SELECT id, property_name, property_type_category, review_score, am
便利设施类别
和父路径
列是JSONB
列,其值分别为[“电视”、“空调”]和[“20000”、“20100”、“203”]。除此之外,其他列是正常的varchar
和numeric
类型。我有大约250万行,主键在id
上,它被索引了。基本上,当rp.parent\u路径匹配多行时,初始CTE部分需要时间
样本数据集:
WITH CTE AS
(
SELECT id,
property_name,
property_type_category,
review_score,
amenity_category.name,
count(*) AS cnt FROM table_name rp,
jsonb_array_elements_text(rp.amenity_categories) amenity_category(name)
WHERE rp.parent_path ? '203' AND number_of_review >= 1
GROUP BY amenity_category.name,id
),
CTE2 as
(
SELECT id, property_name,property_type_category,name,
ROW_NUMBER() OVER (PARTITION BY property_type_category,
name ORDER BY review_score DESC),
COUNT(id) OVER (PARTITION BY property_type_category,
name ORDER BY name DESC)
FROM CTE
)
SELECT id, property_name, property_type_category, name, COUNT
FROM CTE2
where row_number = 1
当前查询:
WITH CTE AS
(
SELECT id,
property_name,
property_type_category,
review_score,
amenity_category.name,
count(*) AS cnt FROM table_name rp,
jsonb_array_elements_text(rp.amenity_categories) amenity_category(name)
WHERE rp.parent_path ? '203' AND number_of_review >= 1
GROUP BY amenity_category.name,id
),
CTE2 as
(
SELECT id, property_name,property_type_category,name,
ROW_NUMBER() OVER (PARTITION BY property_type_category,
name ORDER BY review_score DESC),
COUNT(id) OVER (PARTITION BY property_type_category,
name ORDER BY name DESC)
FROM CTE
)
SELECT id, property_name, property_type_category, name, COUNT
FROM CTE2
where row_number = 1
电流输出:
WITH CTE AS
(
SELECT id,
property_name,
property_type_category,
review_score,
amenity_category.name,
count(*) AS cnt FROM table_name rp,
jsonb_array_elements_text(rp.amenity_categories) amenity_category(name)
WHERE rp.parent_path ? '203' AND number_of_review >= 1
GROUP BY amenity_category.name,id
),
CTE2 as
(
SELECT id, property_name,property_type_category,name,
ROW_NUMBER() OVER (PARTITION BY property_type_category,
name ORDER BY review_score DESC),
COUNT(id) OVER (PARTITION BY property_type_category,
name ORDER BY name DESC)
FROM CTE
)
SELECT id, property_name, property_type_category, name, COUNT
FROM CTE2
where row_number = 1
因此,我的基本问题是,有没有其他方法可以重新编写此查询或优化当前查询?如果可以安全地假设
便利设施类别中的数组元素是不同的(没有重复的数组元素),我们可以从根本上简化为:
选择DISTINCT ON(属性\类型\类别,ac.name)
id、属性名称、属性类型、类别、ac.name
,COUNT(*)超过(按属性\类型\类别划分,ac.name)作为计数
从表\u name rp、jsonb\u数组\u元素\u文本(rp.amentity\u类别)ac(名称)
“你的路径在哪里?”203'
和审查次数>=1
按属性、类型、类别、ac.name、评审、评分说明排序;
如果review\u score
可以为空,则:
。。。
按属性、类型、类别、ac.name、评审、分数说明最后为空排序;
这是有效的,因为DISTINCT ON
作为最后一步(在窗口函数之后)应用。见:
parent\u path
和number\u of\u review
可能应该编制索引。取决于的数据分布和选择性,其中
条件是您未披露的
关于
上的不同
假设
id
为notnull
,count(*)
更快,相当于count(id)
,如果可以安全地假设ament\u类别中的数组元素是不同的(没有重复的数组元素),我们可以从根本上简化为:
选择DISTINCT ON(属性\类型\类别,ac.name)
id、属性名称、属性类型、类别、ac.name
,COUNT(*)超过(按属性\类型\类别划分,ac.name)作为计数
从表\u name rp、jsonb\u数组\u元素\u文本(rp.amentity\u类别)ac(名称)
“你的路径在哪里?”203'
和审查次数>=1
按属性、类型、类别、ac.name、评审、评分说明排序;
如果review\u score
可以为空,则:
。。。
按属性、类型、类别、ac.name、评审、分数说明最后为空排序;
这是有效的,因为DISTINCT ON
作为最后一步(在窗口函数之后)应用。见:
parent\u path
和number\u of\u review
可能应该编制索引。取决于的数据分布和选择性,其中
条件是您未披露的
关于
上的不同
假设
id
为notnull
,count(*)
更快,相当于count(id)
,请描述您试图做什么。@GordonLinoff先生,我试图通过舒适性组合窗口获取每个属性类型类别的计数,并在每个窗口上获取顶部id和属性名称。例如,如果您看到输出,类别:小屋和舒适性:Tv的计数为273,我从273中获取id,property_name
顶行的值请描述您试图执行的操作。@GordonLinoff先生,我正试图通过舒适性组合窗口获取每个属性类型类别的计数,并在每个窗口上获取顶行id和属性名称。例如,如果您看到输出,类别:客舱和便利设施:电视有273个计数,从这273个计数中,我抓取了排在前的id,property\u name
值谢谢您的回答,先生,我会在检查此优化时与您联系。非常感谢您的回答。它很有效,计划和执行时间都比以前好。谢谢您的回答,先生,我会在检查此优化时与您联系。非常感谢你的回答。它很有效,计划和执行时间都比以前好。