2016-03-25 12 views
0

ile OR koşuluMYSQL - Ben 3 Tablolar (3 Milyon satır var) CompanyMaster, Token1, Token2 ve ardından masa yapıdır

CompanyMaster, JOIN

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 

WebDomain'i Token1 ve Token2 tablolarını kullanarak CompanyMaster tablosundan almak istiyorum.

Sorgu i

SELECT WebDomain FROM CompanyMaster WHERE CompanyUID IN (
SELECT CompanyUID FROM Token1 WHERE Token='appleinc' 
UNION 
SELECT CompanyUID FROM Token2 WHERE Token='d012233:q122100:') 

Bu sorgu sonucu elde etmek için yaklaşık 30 saniye sürer, is kullanıyorum. Yalnız alt sorgusu çalıştırdım, < 100 mili-second.So problemi IN koşulu ile alıyor.

I katılması ile sorgu yerini aldı ve bu < 200 ms

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:' 

Ancak yukarıdaki terimi sorun yürütülüyor olduğu, tk1.Alias ​​= 'Khronos Group'dan lisanslı Apple' ya da tk2.Alias ​​= 'd012233 edin: q122100: 'boş satır olarak çıktı veriyor. Ama tek bir koşul eşleştiğinde bile eşleşen satırları istiyorum.

Lütfen bunun nasıl çözüleceğine nasıl yardımcı olabilirim? Ve ayrıca sorgunun 10 milisaniyeden daha az bir zamanda yürütülmesini istiyorum. Bu ulaşılabilir mi?

+0

Cevaplardan herhangi biri ihtiyaçlarınızı karşıladı mı? Bir yorum bırakabilir misiniz? – trincot

cevap

1
o çıktıda dava için hiç fark olacak gibi kesinlikle UNION ile daha UNION ALL ile daha iyi performans elde etmelidir

ancak 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:') 

Ancak, dış sorguda UNION koymak olsaydı sadece benzersiz değerleri almak için muhtemelen önemlidir İşte

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:' 

, bu nedenlegerekir: bu, böyle bile daha iyi performans verebilir ALL olmadan 0 burada.

0

Kaydınızı toke1 ve token2 temel alınarak filtrelemek için nerede kullanabilirsiniz. İhtiyacınıza dayanarak bu maddeyi değiştirebilirsiniz.

Lütfen aşağıdaki SQL'i kontrol edin. Umarım probleminizi çözecektir. c.CompanyUID, c.WebDomain SOL CompanyMaster c DAN

tk2.CompanyUID = c.CompanyUID WHERE tk1.Token İLİŞKİN Token2 TK2 artır tk1.CompanyUID = c.CompanyUID SOLUNDAN Token1 TK1 artır SEÇ = '123' VEYA tk2.Token = 'xyz';

+0

Bunu test ettiniz mi? Bu, Token1'in '123' olduğu bir şirket için bir sonuç vermeyecek, ancak Token2'nin bu şirket için hiç bir kaydı bulunmuyor. Öte yandan, Token2'nin bu şirket için birçok kaydı olduğu zaman çiftler verecektir. Ayrıca, cevabınızı SQL ifadesine kod formatı vermek için düzenledim. Bunu en az 4 alanlı bloğun içine girerek yaparsınız. – trincot

+0

Evet. Yaptım. Bu OR cümlesidir. Tek bir gerçek durum eşleşen şirket kaydına dönecektir. Bir şey daha. Evet, yinelenen kayıtları döndürecektir. Bundan kaçınmak için, eşleşen şirketlerin benzersiz kayıtlarını bulmak için grubu grupla kullanabilirsiniz. –

+0

Söylediğiniz gibi çalışmaz, çünkü iç birleşimleri uygularsınız. Ayrıca, SQL ifadenizi kod olarak biçimlendirirseniz iyi olur. – trincot