我有3个表CompanyMaster(有300万行),Token1,Token2和表结构,
CompanyMaster
CREATE TABLE `CompanyMaster` (
`CompanyUID` int(11) NOT NULL AUTO_INCREMENT,
`WebDomain` varchar(150) DEFAULT NULL,
`CompanyPrimaryName` varchar(200) DEFAULT NULL,
PRIMARY KEY (`CompanyUID`)
) ENGINE=InnoDB AUTO_INCREMENT=3941244 DEFAULT CHARSET=latin1
TOKEN1
CREATE TABLE `Token1`(
`CompanyUID` int(11) NOT NULL,
`Token` varchar(50) NOT NULL,
KEY `Token` (`Token`),
KEY `CompanyUID` (`CompanyUID`),
CONSTRAINT `CompanyAlias4_ibfk_1` FOREIGN KEY (`CompanyUID`) REFERENCES `CompanyMaster` (`CompanyUID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Token2
CREATE TABLE `Token2` (
`CompanyUID` int(11) NOT NULL,
`Token` varchar(100) NOT NULL,
KEY `Token` (`Token`),
KEY `CompanyUID` (`CompanyUID`),
CONSTRAINT `CompanyAlias5_ibfk_1` FOREIGN KEY (`CompanyUID`) REFERENCES `CompanyMaster` (`CompanyUID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
我想使用Token1和Token2表从CompanyMaster表中获取WebDomain。
我正在使用的查询是,
SELECT WebDomain FROM CompanyMaster WHERE CompanyUID IN (
SELECT CompanyUID FROM Token1 WHERE Token='appleinc'
UNION
SELECT CompanyUID FROM Token2 WHERE Token='d012233:q122100:')
此查询需要将近30秒才能获得结果。我单独执行了子查询,它正在执行< 100毫秒。所以问题出在IN状态。
我用join替换了查询,它在<中执行了200毫秒,
SELECT c.CompanyUID FROM `CompanyMaster` c
JOIN `Token1` tk1
ON tk1.CompanyUID = c.CompanyUID AND tk1.Token= 'appleinc'
JOIN `Token2` tk2
ON tk2.CompanyUID = c.CompanyUID AND tk2.Token= 'd012233:q122100:'
但上述查询的问题是,如果tk1.Alias ='appleinc'或tk2.Alias ='d012233:q122100:'失败则将输出作为空行。但即使只有一个条件匹配,我也想要匹配的行。
请帮我解决这个问题?而且我还希望查询在不到10毫秒的时间内执行。它可以实现吗?
答案 0 :(得分:1)
你应该使用UNION ALL
而不是UNION
获得更好的效果,因为它在输出中的情况没有区别,但是it does not need to filter out duplicates like UNION
does:
SELECT WebDomain
FROM CompanyMaster
WHERE CompanyUID IN
( SELECT CompanyUID
FROM Token1
WHERE Token = 'appleinc'
UNION ALL
SELECT CompanyUID
FROM Token2
WHERE Token = 'd012233:q122100:')
但是,如果你将UNION
放在外部查询中,它甚至可以提供更好的性能,如下所示:
SELECT WebDomain
FROM CompanyMaster m
INNER JOIN Token1 t ON t.CompanyUID = m.CompanyUID
WHERE Token = 'appleinc'
UNION
SELECT WebDomain
FROM CompanyMaster m
INNER JOIN Token2 t ON t.CompanyUID = m.CompanyUID
WHERE Token = 'd012233:q122100:'
此处仅获取唯一值非常重要,因此您需要UNION
而不需要ALL
。
答案 1 :(得分:0)
您可以使用where子句根据toke1和token2过滤记录。根据您的要求,您可以更改该条款。
请检查以下SQL。希望它能解决你的问题。
选择
c.CompanyUID,c.WebDomain
从
CompanyMaster
c
LEFT JOIN Token1
tk1 ON tk1.CompanyUID = c.CompanyUID
LEFT JOIN Token2
tk2 ON tk2.CompanyUID = c.CompanyUID
哪里
tk1.Token ='123'或tk2.Token ='xyz';