[英]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)
我想要得到的是:添加对另一个表的查询,我认为可以通过两种方式完成:
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)
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.