簡體   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