繁体   English   中英

从多个表查询产品并组合结果的最有效方式?

[英]Most performant way to query products from multiple tables and combine results?

在具有多个制造商的系统中,我基本上有两个核心类别的产品。 系统中的当前查询仅用于处理一种产品。

这是代码:

SELECT DISTINCT c.id
FROM "Config" c
JOIN "FirstProduct" fp ON c.id = fp.widget
JOIN "TheSupplier" ts ON ts.name = fp.manufacturer
LEFT JOIN "ProductOffer" o ON (o.app = ts.app)
WHERE ts.app = ?appId
AND (?mlid IS NULL OR ?mlid = fp.manufacturer)
AND (o.company IS NULL OR o.manufacturer <> fp.manufacturer)

我想要得到的是:添加对另一个表的查询,我认为可以通过两种方式完成:

  1. 有效地在一个查询中完成两个查询
SELECT DISTINCT c.id
FROM "Config" c
JOIN "FirstProduct" fp ON c.id = fp.widget fpw
JOIN "SecondProduct" sp ON c.id = sp.widget spw
JOIN "TheSupplier" ts ON ts.name = fp.manufacturer
LEFT JOIN "ProductOffer" o ON (o.app = ts.app)
WHERE ts.app = ?appId
AND (?mlid IS NULL OR ?mlid = fp.manufacturer)
AND (o.company IS NULL OR o.manufacturer <> fp.manufacturer)
  1. 进行两个单独的查询,并对其进行UNION。
with first_product_table as (
SELECT DISTINCT c.id
FROM "Config" c
JOIN "FirstProduct" fp ON c.id = fp.widget
JOIN "TheSupplier" ts ON ts.name = fp.manufacturer
LEFT JOIN "ProductOffer" o ON (o.app = ts.app)
WHERE ts.app = ?appId
AND (?mlid IS NULL OR ?mlid = fp.manufacturer)
AND (o.company IS NULL OR o.manufacturer <> fp.manufacturer)
) ,
second_product_table as (
SELECT DISTINCT c.id
FROM "Config" c
JOIN "SecondProduct" sp ON c.id = sp.widget spw
JOIN "TheSupplier" ts ON ts.name = fp.manufacturer
LEFT JOIN "ProductOffer" o ON (o.app = ts.app)
WHERE ts.app = ?appId
AND (?mlid IS NULL OR ?mlid = fp.manufacturer)
AND (o.company IS NULL OR o.manufacturer <> fp.manufacturer)
)
select * from first_product_table
UNION
second_product_table

这将在生产系统中,因此对性能的关注并非无关紧要。

这两个查询不相等。 根据您的描述,第二个将产生您想要的结果。 最后我做了一个小修正:

with
first_product_table as (
  SELECT DISTINCT c.id
  FROM "Config" c
  JOIN "FirstProduct" fp ON c.id = fp.widget
  JOIN "TheSupplier" ts ON ts.name = fp.manufacturer
  LEFT JOIN "ProductOffer" o ON o.app = ts.app
  WHERE ts.app = ?appId
  AND (?mlid IS NULL OR ?mlid = fp.manufacturer)
  AND (o.company IS NULL OR o.manufacturer <> fp.manufacturer)
),
second_product_table as (
  SELECT DISTINCT c.id
  FROM "Config" c
  JOIN "SecondProduct" sp ON c.id = sp.widget spw
  JOIN "TheSupplier" ts ON ts.name = fp.manufacturer
  LEFT JOIN "ProductOffer" o ON (o.app = ts.app)
  WHERE ts.app = ?appId
  AND (?mlid IS NULL OR ?mlid = fp.manufacturer)
  AND (o.company IS NULL OR o.manufacturer <> fp.manufacturer)
)
select * from first_product_table
UNION
select * from second_product_table

如果您担心性能,则需要确保您拥有正确的索引。 当指定参数mlid时,以下两个索引是最重要的:

create index ix1 on FirstProduct (manufacturer);
create index ix2 on SecondProduct (manufacturer);

然后,如果查询仍然很慢,则可以尝试:

create index ix3 on TheSupplier (name, app);
create index ix4 on ProductOffer (app, company, manufacturer);

最后说明 :请考虑以下条件o.manufacturer <> fp.manufacturer可能会过滤掉您想要的行,因为它有效地否定了外部o.manufacturer <> fp.manufacturer ,将其转换为内部 o.manufacturer <> fp.manufacturer 也许您希望每个部分的最后四行如下所示:

  LEFT JOIN "ProductOffer" o ON (o.app = ts.app)
    AND (o.company IS NULL OR o.manufacturer <> fp.manufacturer)
  WHERE ts.app = ?appId
  AND (?mlid IS NULL OR ?mlid = fp.manufacturer)

但这只是猜测,因为我不完全了解您的要求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM