Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL优化包含CTE窗口函数的查询性能_Sql_Postgresql_Common Table Expression_Window Functions_Jsonb - Fatal编程技术网

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
值谢谢您的回答,先生,我会在检查此优化时与您联系。非常感谢您的回答。它很有效,计划和执行时间都比以前好。谢谢您的回答,先生,我会在检查此优化时与您联系。非常感谢你的回答。它很有效,计划和执行时间都比以前好。