SELECT p.*
FROM (
SELECT ProductID,ProductName,ProductCode,SampleRefNum
FROM products
WHERE hidden = 'N'
UNION ALL
SELECT product_variants.ProductID,products.ProductName,product_variants.ProductCode,product_variants.SampleRefNum
FROM product_variants
JOIN products
ON product_variants.ProductID = products.ProductID
) AS p
LEFT JOIN stock_list AS s
ON p.ProductCode = s.ProductCode OR p.SampleRefNum = s.SampleRefNum
WHERE s.ProductCode IS NULL AND p.ProductCode IS NOT NULL AND p.ProductCode <> "" OR s.SampleRefNum IS NULL AND p.SampleRefNum IS NOT NULL AND p.SampleRefNum <> ""
上面的查询非常慢,1分钟。如果我只是快速做联盟部分。或者只使用产品表而不是快速结合
(我在这做什么?) 产品有变种,所以我结合产品和产品变体,以获得具有产品代码和样品ref num的项目列表。 然后我加入库存清单(包含大约50 000行产品代码和来自另一个系统的示例参考代码的表),这样我就可以得到任何没有匹配的ProductCode或SampleRefNum的记录列表
------------修改
我在所有表格上的ProductID,ProductCode,SampleRefNum上都有索引
- 这很快-----
SELECT p.ProductID,p.ProductName,p.ProductCode,p.SampleRefNum FROM products AS p
LEFT JOIN stock_list AS s
ON p.ProductCode = s.ProductCode OR p.SampleRefNum = s.SampleRefNum
WHERE p.Hidden = 'N' AND (s.ProductCode IS NULL AND p.ProductCode IS NOT NULL AND p.ProductCode <> "" OR s.SampleRefNum IS NULL AND p.SampleRefNum IS NOT NULL AND p.SampleRefNum <> "" )
AND (p.ProductID NOT IN(SELECT ProductID FROM product_variants) )
---这需要10秒
SELECT p.*
FROM (
SELECT ProductID,ProductName,ProductCode,SampleRefNum
FROM products
WHERE hidden = 'N'
) AS p
LEFT JOIN stock_list AS s
ON p.ProductCode = s.ProductCode OR p.SampleRefNum = s.SampleRefNum
WHERE s.ProductCode IS NULL AND p.ProductCode IS NOT NULL AND p.ProductCode <> "" OR s.SampleRefNum IS NULL AND p.SampleRefNum IS NOT NULL AND p.SampleRefNum <> ""
答案 0 :(得分:3)
一般join
or
条件会变慢。我建议您使用exists
或更简单的left joins
对查询进行重新措辞。但是,您可以使用两个左连接尝试此操作,看看是否符合您的要求:
SELECT p.*
FROM (SELECT ProductID, ProductName, ProductCode, SampleRefNum
FROM products p
WHERE hidden = 'N'
UNION ALL
SELECT pv.ProductID, p.ProductName, pv.ProductCode, pv.SampleRefNum
FROM product_variants pv JOIN
products p
ON pv.ProductID = p.ProductID
) p LEFT JOIN
stock_list s1
ON p.ProductCode = s1.ProductCode LEFT JOIN
stock_list s2
ON p.SampleRefNum = s2.SampleRefNum
WHERE (s1.ProductCode IS NULL AND p.ProductCode IS NOT NULL AND p.ProductCode <> '') OR
(s2.SampleRefNum IS NULL AND p.SampleRefNum IS NOT NULL AND p.SampleRefNum <> '')
要使其正常运行,您需要stock_list
上的两个索引:stock_list(ProductCode)
和stock_list(SampleRefNum)
。
注意:如果一个键上的stock_list
中存在多个匹配而另一个键没有匹配,则可能会返回多行。我认为您的原始查询具有相同的问题。使用not exists
子句可以解决这个问题。
编辑:
not exists
看起来像:
WHERE (NOT EXISTS (select 1
from stock_list s1
where p.ProductCode = s1.ProductCode
) and
p.ProductCode is not null and p.ProductCode <> ''
) AND
(NOT EXISTS (select 1
from stock_list s2
where p.SampleRefNum = s1.SampleRefNum
) and
p.SampleRefNum is not null and p.SampleRefNum <> ''
)
您可以从join
子句中删除from
(这需要相同的索引)。