PostgreSQL重写或在查询中部分以提高性能

发布于 2025-02-05 12:46:36 字数 1869 浏览 2 评论 0原文

我正在尝试在以下查询下重写以提高性能。查询在类别表中的每个密钥中对同一产品表有两个子查询(SO扫描两次),因此查询具有独特的速度,并且查询很慢。

-- original query
select Distinct on (p.value,c.key) c.key, c.type_key, c.status, c.created_by 
from category c
LEFT JOIN products p
on p.category_key=c.key
where c.type_key=4  
and p.status='active' and c.status='active'
and p.attribute_key=6
and ( 
   (EXISTS (SELECT * from products p1
                  WHERE p1.attribute_key=2 
                   AND p1.category_key=c.key 
                   AND ((value in ('Active', 'active')))
                   AND p1.status='active'
        ))
    OR(NOT EXISTS(SELECT * from products p1
                   WHERE p1.attribute_key=2 
                    AND p1.category_key=c.key 
                    AND p1.status='active') 
        )) 
order by p.value

查询从类别表返回键,如果type_key = 4和category.status ='active'and attribute_key = 6,而

  1. 产品表具有attribute_key = 2 and value ='active'或'active'或'active'and status and status ='active。 (这是子查询中的一部分),
  2. 即使产品表没有任何属性_key或attribute_key!= 2 type_key = 4的记录。 (这是或(不存在的)在子查询中)

示例数据在这里

由于产品表上的谓词几乎相同。我尝试了重写,以下是我的最新查询

select Distinct on (p.value,c.key) c.key, c.type_key, c.status, c.created_by 
from category c
LEFT JOIN products p
on p.category_key=c.key
where c.type_key=4  
and p.attribute_key in (2,6) 
and p.status='active' and c.status='active'
and  (p.attribute_key !=2 -- NOT EXISTS
   OR (value in ('Active', 'active'))) 
order by p.value

,但最新的查询返回了一些重复,即使有明显的重复。

可以通过编写另一种方式或更改或部分查询来改善原始查询

I'm trying to re-write below query to improve performance. Query has Distinct on and query is slow because of OR part has two sub queries for same products table (so twice scanning) for the each key in category table.

-- original query
select Distinct on (p.value,c.key) c.key, c.type_key, c.status, c.created_by 
from category c
LEFT JOIN products p
on p.category_key=c.key
where c.type_key=4  
and p.status='active' and c.status='active'
and p.attribute_key=6
and ( 
   (EXISTS (SELECT * from products p1
                  WHERE p1.attribute_key=2 
                   AND p1.category_key=c.key 
                   AND ((value in ('Active', 'active')))
                   AND p1.status='active'
        ))
    OR(NOT EXISTS(SELECT * from products p1
                   WHERE p1.attribute_key=2 
                    AND p1.category_key=c.key 
                    AND p1.status='active') 
        )) 
order by p.value

Query returns keys from category table if type_key=4 and category.status='active' and attribute_key=6 and

  1. products table has attribute_key=2 and value='Active' or 'active' and status='active. (this is EXISTS part in sub-query)
  2. even if products table doesn't have any attribute_key or has attribute_key!=2 records for type_key=4. (this is OR( NOT EXISTS) part in sub-query)

Sample data is here dbfiddle

Since predicates on the products table are almost same. I tried re-write and below is my latest query

select Distinct on (p.value,c.key) c.key, c.type_key, c.status, c.created_by 
from category c
LEFT JOIN products p
on p.category_key=c.key
where c.type_key=4  
and p.attribute_key in (2,6) 
and p.status='active' and c.status='active'
and  (p.attribute_key !=2 -- NOT EXISTS
   OR (value in ('Active', 'active'))) 
order by p.value

But latest query returns some duplicates even though there is Distinct ON.

enter image description here

Is it possible to improve original query by writing another way or changing OR part in query

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文