假设我需要查询一家公司的员工。我有一个表“交易”,其中包含每笔交易的数据。
CREATE TABLE `transactions` (
`transactionID` int(11) unsigned NOT NULL,
`orderID` int(11) unsigned NOT NULL,
`customerID` int(11) unsigned NOT NULL,
`employeeID` int(11) unsigned NOT NULL,
`corporationID` int(11) unsigned NOT NULL,
PRIMARY KEY (`transactionID`),
KEY `orderID` (`orderID`),
KEY `customerID` (`customerID`),
KEY `employeeID` (`employeeID`),
KEY `corporationID` (`corporationID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
在该表中查询员工相当简单,但有一个问题:每个员工都会注册一次交易记录,因此一个公司的每个订单可能有多个记录。
例如,如果公司 1 的员工 A 和 B 都参与向公司 2 销售吸尘器,则“交易”表中将有两条记录;每位员工一个,公司 1 两个。不过,这不能影响结果。公司 1 的一项交易,无论涉及多少员工,都必须被视为一项交易。
很简单,我想。我将在派生表上进行联接,如下所示:
SELECT corporationID FROM transactions JOIN (SELECT DISTINCT orderID FROM transactions WHERE corporationID = 1) AS foo USING (orderID)
该查询返回与公司 1 进行过交易的公司列表。这正是我所需要的,但速度非常慢,因为 MySQL 无法使用corporationID 索引来确定派生表。据我所知,MySQL 中的所有子查询/派生表都是这种情况。
我还尝试单独查询 orderID 集合并使用大得离谱的 IN() 子句(通常超过 100 000 个 ID),但事实证明 MySQL 在使用大得离谱的 IN() 子句上的索引时存在问题,如下所示:好吧,结果查询时间并没有改善。
是否还有其他可用选项,或者我是否已用尽它们?
最佳答案
如果我了解您的要求,您可以尝试一下。
select distinct t1.corporationID
from transactions t1
where exists (
select 1
from transactions t2
where t2.corporationID = 1
and t2.orderID = t1.orderID)
and t1.corporationID != 1;
或者这个:
select distinct t1.corporationID
from transactions t1
join transactions t2
on t2.orderID = t1.orderID
and t1.transactionID != t2.transactionID
where t2.corporationID = 1
and t1.corporationID != 1;
关于mysql - 使用大型 IN() 子句或派生表联接优化 MySQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2091777/