[英]Is there a more efficient approach other than using a co-related query for solving the below problem?
提示:本站为国内最大中英文翻译问答网站,提供中英文对照查看,鼠标放在中文字句上可显示英文原文。
我有三个数据库表:
product
product_manufacturer
product_manufacturer_warranties
。product 表与 product_manufacturer 具有一对一的映射关系,product_id 存储在 product_manufacturer 表中。 product_manufactuer 表与 product_manufacturer_warranties 表具有一对多映射。
我需要编写一个查询来检索 product 表中的所有列和其他两个列,这两个列可用于分别确定 product 和 product_manufacturer 以及 product_manufacturer 和 product_manufactuer_warranties 是否存在有效连接。
我编写了以下可以处理上述情况的相关查询:
select product.*, pm.web_id,
( SELECT count(*)
FROM product_manufacturer_warranty pmw
WHERE pm.web_id = pmw.product_manufacturer_id)
AS total_warranties
from product
left join product_manufacturer pm on product.web_id = pm.product_id
我想知道在 PostgreSQL 服务器上使用 SQL 是否有更好或更有效的方法来实现此目的。
进行一次聚合,然后加入结果:
select product.*,
pm.web_id,
pmw.total_warranties
from product
left join product_manufacturer pm on product.web_id = pm.product_id
left join (
SELECT product_manufacturer_id, count(*) as total_warranties
FROM product_manufacturer_warranty pmw
group by product_manufacturer_id
) as pmw on pm.web_id = pmw.product_manufacturer_id)
由于您只对bare existence感兴趣,所以不要运行可能更昂贵的
。count()
在对(可能很大的)表格进行分页时,不要计算所有产品的数量,这会更加昂贵。
这应该为您提供最佳性能:
向上翻页:
SELECT p.*
, m.product_id IS NOT NULL AS has_maufacturer
, EXISTS (
SELECT FROM product_manufacturer_warranty w
WHERE w.product_manufacturer_id = m.web_id
) AS has_warranties
FROM (
SELECT *
FROM product
WHERE product_id > $max_product_id_of_last_page
-- more filters here?
ORDER BY product_id
LIMIT $page_size
) p
LEFT JOIN product_manufacturer m ON p.web_id = m.product_id
查询返回您要求的内容:
product 表中的所有列和其他两个列,可用于确定
product
和product_manufacturer
以及product_manufacturer
和product_manufactuer_warranties
是否存在有效连接。
p
中第 select 个感兴趣的产品product_manufacturer
。 不能乘行,定义为一对一关系!EXISTS
检查是否存在。 如果可以有很多相关行,成本会大大降低。 看:
相应地向下翻页:
SELECT p.*
, m.product_id IS NOT NULL AS has_maufacturer
, EXISTS (
SELECT FROM product_manufacturer_warranty w
WHERE w.product_manufacturer_id = m.web_id
) AS has_warranties
FROM (
SELECT *
FROM product
WHERE product_id < $min_product_id_of_last_page
-- more filters here?
ORDER BY product_id DESC
LIMIT $page_size
) p
LEFT JOIN product_manufacturer m ON p.web_id = m.product_id
ORDER BY product_id;
适应您的实际排序顺序。 这对于多个ORDER BY
表达式来说更棘手。 无论哪种方式,除非您的桌子非常小,否则不要LIMIT
/ OFFSET
。 看:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.