[英]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.