2016-03-25 14 views
0

Ich habe 3 Tabellen Companymaster (davon 3 Millionen Zeilen hat), Token1, Token2 und die Tabellenstruktur ist,MYSQL - JOIN mit OR-Bedingung

Company

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

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 

Ich möchte die WebDomain aus der Tabelle CompanyMaster mithilfe der Tabellen Token1 und Token2 abrufen.

Der Query ich verwende heißt,

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

Diese Abfrage fast 30 Sekunden dauert das Ergebnis zu erhalten. Ich habe die Sub-Abfrage allein ausgeführt, die < 100 Millisekunden dauert. So ist das Problem mit der IN-Bedingung.

ich die Abfrage mit Join ersetzt und es wird in < 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:' 

Aber das Problem mit obiger Abfrage ausgeführt wird, wenn tk1.Alias ​​= 'appleinc' oder tk2.Alias ​​= ‚d012233: q122100: 'schlägt fehl, es gibt Ausgabe als leere Zeile. Aber ich möchte die übereinstimmenden Zeilen auch wenn nur eine Bedingung übereinstimmt.

Bitte helfen Sie mir, dieses zu lösen? Und ich möchte auch, dass die Abfrage in weniger als 10 Millisekunden ausgeführt wird. Ist es erreichbar?

+0

Hat eine der Antworten Ihren Anforderungen entsprochen? Könnten Sie einen Kommentar hinterlassen? – trincot

Antwort

1

Sie sicherlich eine bessere Leistung mit UNION ALL als mit UNION bekommen sollte, da es keinen Unterschied für Ihren Fall in der Ausgabe haben, aber 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:') 

Wenn Sie jedoch die UNION in der äußeren Abfrage setzen würde geben, es könnte sogar eine bessere Leistung, wie folgt aus:

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

Hier ist es wohl wichtig ist, nur auf eindeutige Werte zu erhalten, so müssen Sie UNION ohne ALL hier.

0

Sie können where-Klausel verwenden, um Ihren Datensatz auf der Grundlage von toke1 und token2 zu filtern. Auf der Grundlage Ihrer Anforderung können Sie diese Klausel ändern.

Bitte überprüfen Sie folgende SQL. Hoffe es wird dein Problem lösen.

SELECT c.CompanyUID, c.WebDomain FROM CompanyMaster c LEFT JOIN Token1 TK1 ON tk1.CompanyUID = c.CompanyUID LEFT JOIN Token2 TK2 ON tk2.CompanyUID = c.CompanyUID WHERE tk1.Token = '123' ODER tk2.Token = 'xyz';

+0

Hast du das getestet? Dies ergibt kein Ergebnis für ein Unternehmen, wenn Token1 "123" hat, aber Token2 hat überhaupt keine Datensätze für dieses Unternehmen. Auf der anderen Seite wird es Duplikate geben, wenn Token2 viele Datensätze für diese Firma hat. Außerdem habe ich Ihre Antwort bearbeitet, um der SQL-Anweisung das Code-Format zu geben. Dies tun Sie, indem Sie diesen Block mit mindestens 4 Leerzeichen einrücken. – trincot

+0

Ja. Ich tat. Es ist OR-Klausel. Eine wahre Bedingung wird den übereinstimmenden Firmendatensatz zurückgeben. Eine Sache noch. Ja, es werden doppelte Datensätze zurückgegeben. Um dies zu vermeiden, können Sie die Gruppierung nach Klausel verwenden, um eindeutige Datensätze übereinstimmender Unternehmen zu finden. –

+0

Es funktioniert nicht wie du sagst, weil du innere Verbindungen anlegst. Außerdem wäre es schön, wenn Sie Ihre SQL-Anweisung als Code formatieren würden. – trincot