使用union和left join的mysql查询速度较慢
上面的查询非常慢,1分钟。如果我只做联合部分,它会很快。或者只使用products表,而不使用union表 我在这里干什么? 产品有变体,所以我将产品和产品变体结合起来,以获得一个包含产品代码和示例参考编号的项目列表。 然后,我加入到库存列表表,其中包含来自另一个系统的大约50000行产品代码和示例参考代码,这样我就可以得到一个没有匹配ProductCode或SampleRefNum的记录列表 ------编辑 我在所有表的ProductID、ProductCode和sampleefnum上都有索引 -这很快---使用union和left join的mysql查询速度较慢,mysql,join,union,Mysql,Join,Union,上面的查询非常慢,1分钟。如果我只做联合部分,它会很快。或者只使用products表,而不使用union表 我在这里干什么? 产品有变体,所以我将产品和产品变体结合起来,以获得一个包含产品代码和示例参考编号的项目列表。 然后,我加入到库存列表表,其中包含来自另一个系统的大约50000行产品代码和示例参考代码,这样我就可以得到一个没有匹配ProductCode或SampleRefNum的记录列表 ------编辑 我在所有表的ProductID、ProductCode和sampleefnum上都有
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 <> ""
--这需要10秒
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) )
一般来说,加入一个或条件将是缓慢的。我建议您使用exists或更简单的左连接重新表述查询。但是,您可以尝试使用两个左连接,看看这是否符合您的要求:
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 <> ""
您将从from子句中删除连接,这需要相同的索引。您可以发布解释计划吗?你检查过索引吗?如果你愿意,考虑下面这个简单的两步过程:1。如果您还没有这样做,请提供适当的DDL和/或SQLFIDLE,以便我们可以更轻松地复制问题。2.如果尚未这样做,请提供与步骤1中提供的信息相对应的所需结果集。
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 <> '')
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 <> ''
)