MYSQL - 使用OR条件加入

时间:2016-03-25 10:37:10

标签: mysql select join

我有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毫秒的时间内执行。它可以实现吗?

2 个答案:

答案 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';