多个MySQL来自多个表的OR

时间:2017-03-25 16:01:12

标签: mysql

SELECT m.SKU, m.AltSKU, e.OrderLineItemID, e.SKU, e.Quantity, e.TransactionPrice, e.CreatedTime
FROM MasterSKU m, eBayOrders_store1 e
WHERE m.SKU = e.SKU  
AND 
m.AltSKU IS NOT NULL
AND 
e.CreatedTime BETWEEN '2017-03-16 00:00:00' AND '2017-03-16 23:59:59';

查询速度非常快。

  

查询耗时0.0105秒。

但是当我尝试组合所有eBayOrder表时,如下:

SELECT m.SKU, m.AltSKU, e.OrderLineItemID, e.SKU, e.Quantity, e.TransactionPrice, e.CreatedTime
FROM MasterSKU m, eBayOrders_store1 e, eBayOrders_store2 z, eBayOrders_store3 d, eBayOrders_store4 c
WHERE (m.SKU = e.SKU) OR (m.SKU = z.SKU) OR (m.SKU = d.SKU) OR (m.SKU = c.SKU)  
AND 
m.AltSKU IS NOT NULL
AND 
e.CreatedTime BETWEEN '2017-03-16 00:00:00' AND '2017-03-16 23:59:59';

它基本上冻结了MySQL连接。我检查了查询,它正在运行尝试获取超过10分钟的数据。我不得不进入SSH并手动终止进程/查询以阻止它。

有什么问题?

2 个答案:

答案 0 :(得分:2)

评论太长了。

问题在于您正在执行所有表中的cross join,然后过滤掉几行。如果任何条件在两个表之间匹配,那么您将获得与所有其他表中所有行的每个匹配,交叉连接。

我猜这个查询并不接近你想做的事情。它可能会产生一堆重复。输出中可能缺少行。如果一个id只在一个表中,它就不会出现在输出中。

我的建议:提出另一个问题。提供样本数据和所需结果。

答案 1 :(得分:1)

使用UNION s可以加快速度,方法是将每个商店表包含在自己的子查询中(防止它们之间的交叉连接)。

缺点是查询冗余。但是你可以通过用代码生成联合来解决这个问题。

SELECT m.SKU, m.AltSKU, e.OrderLineItemID, e.SKU, e.Quantity, e.TransactionPrice, e.CreatedTime
FROM MasterSKU AS m
INNER JOIN eBayOrders_store1 AS e ON m.SKU = e.SKU  
    AND e.CreatedTime BETWEEN '2017-03-16 00:00:00' AND '2017-03-16 23:59:59'
WHERE m.AltSKU IS NOT NULL
UNION
SELECT m.SKU, m.AltSKU, e.OrderLineItemID, e.SKU, e.Quantity, e.TransactionPrice, e.CreatedTime
FROM MasterSKU AS m
INNER JOIN eBayOrders_store2 AS e ON m.SKU = e.SKU  
    AND e.CreatedTime BETWEEN '2017-03-16 00:00:00' AND '2017-03-16 23:59:59'
WHERE m.AltSKU IS NOT NULL
UNION
SELECT m.SKU, m.AltSKU, e.OrderLineItemID, e.SKU, e.Quantity, e.TransactionPrice, e.CreatedTime
FROM MasterSKU AS m
INNER JOIN eBayOrders_store3 AS e ON m.SKU = e.SKU  
    AND e.CreatedTime BETWEEN '2017-03-16 00:00:00' AND '2017-03-16 23:59:59'
WHERE m.AltSKU IS NOT NULL
UNION    
SELECT m.SKU, m.AltSKU, e.OrderLineItemID, e.SKU, e.Quantity, e.TransactionPrice, e.CreatedTime
FROM MasterSKU AS m
INNER JOIN eBayOrders_store4 AS e ON m.SKU = e.SKU  
    AND e.CreatedTime BETWEEN '2017-03-16 00:00:00' AND '2017-03-16 23:59:59'
WHERE m.AltSKU IS NOT NULL;

您可以通过将UNION放入派生表来简化此操作,但是当您在连接上丢失e.SKU上的密钥时,这可能会对性能产生负面影响:

SELECT m.SKU, m.AltSKU, e.OrderLineItemID, e.SKU, e.Quantity, e.TransactionPrice, e.CreatedTime
FROM MasterSKU AS m
INNER JOIN (
    SELECT * FROM eBayOrders_store1 WHERE CreatedTime BETWEEN '2017-03-16 00:00:00' AND '2017-03-16 23:59:59'
    UNION SELECT * FROM eBayOrders_store2 WHERE CreatedTime BETWEEN '2017-03-16 00:00:00' AND '2017-03-16 23:59:59'
    UNION SELECT * FROM eBayOrders_store3 WHERE CreatedTime BETWEEN '2017-03-16 00:00:00' AND '2017-03-16 23:59:59'
    UNION SELECT * FROM eBayOrders_store4 WHERE CreatedTime BETWEEN '2017-03-16 00:00:00' AND '2017-03-16 23:59:59'
) AS e ON m.SKU = e.SKU  
WHERE m.AltSKU IS NOT NULL;