2016-03-25 25 views
0

とOR条件のJOIN、TOKEN1、Token2やテーブル構造があり、MYSQL - 私は3つのテーブル(3万行を持っている)CompanyMasterを持って

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 

トークン2

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を取得したいとします。

私が使用しているクエリは、このクエリが結果を得るために、ほぼ30秒かかり、

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

です。私は< 100ミリ秒を取っているサブクエリを単独で実行しました。問題はIN条件です。

私は

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

、参加して、それが< 200ミリ秒で実行されていると、クエリを置き換えしかしtk1.Aliasの=「appleinc」またはtk2.Alias =「d012233場合は上記のクエリに問題が、次のとおりです。 q122100: 'は、空の行として出力しています。しかし、条件が1つしか一致しない場合でも、一致する行が必要です。

どうすればこの問題を解決できますか?また、クエリを10ミリ秒未満で実行する必要があります。それは達成可能ですか?

+0

あなたのニーズに合った回答はありますか?あなたはコメントを残すことができますか? – trincot

答えて

1

あなたは確かにそれは出力にあなたのケースのために差がないように、UNIONよりもUNION ALLとのより良いパフォーマンスを得るが、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:' 

ここで、あなたがを必要とするので、唯一の一意の値を取得するために、おそらく重要である。このように、それも、優れたパフォーマンスを与えるかもしれません0はここにALLなし。

0

where句を使用すると、toke1とtoken2に基づいてレコードをフィルタできます。要件に基づいて、その条項を変更することができます。

次のSQLを確認してください。あなたの問題を解決することを願っています。

tk2.CompanyUID = c.CompanyUID WHERE tk1.Token ON Token2 TK2をJOIN tk1.CompanyUID = c.CompanyUID 左側にToken1 TK1をJOIN LEFT C CompanyMaster FROM c.CompanyUID、c.WebDomain を選択= '123' OR tk2.Token = 'xyz';

+0

これはテストしましたか?これは、Token1に '123'があるときは会社の結果を与えませんが、Token2にはその会社のレコードがまったくありません。一方、Token2にはその会社のレコードがたくさんあるときに重複して表示されます。また、私はあなたの答えを編集して、SQL文にコード形式を与えました。あなたは少なくとも4つのスペースでそのブロックをインデントすることでこれを行います。 – trincot

+0

はい。やった。 OR節です。真の条件が1つあれば、一致する会社のレコードが返されます。もう一つ。はい、重複したレコードが返されます。それを回避するために、group by clauseを使用して一致する会社の一意のレコードを見つけることができます。 –

+0

内部結合を適用しているので、あなたの言うように動作しません。また、SQL文をコードとして書式設定するといいでしょう。 – trincot

関連する問題