2017-06-08 9 views
1

約60.000行と約60列の2つ(またはそれ以上)のテーブルを比較する必要があります。大きなMySQLテーブルを比較する

これらの表には、クエリを実行する2つの値があります。クエリの目的は、TABLE_Aに存在する行をカウントすることですが、行の2つの値に基づいてTABLE_Bには存在しません。

私は、次のクエリを実行しました:

SELECT id 
FROM table_a ta 
WHERE NOT EXISTS (
    SELECT id 
    FROM table_b tb 
    WHERE ta.value1=tb.value1 AND ta.value2=tb.value2 
) 

としては、私は上記のコードとその上にいくつかのバリエーションを試してみた、と述べました。しかし、このクエリを実行するには、完了するまでに時間がかかります。私は10秒以内に実行されるソリューションを見つけることを願っています。

次のクエリは、私が試した、とその私が働いていたと思った:

SELECT value1, value2 
FROM (
    SELECT ta.value1, ta.value2 
    FROM table_a ta 
    UNION ALL 
    SELECT tb.value1, tb.value2 
    FROM table_b tb 
) result 
GROUP BY value1, value2 
HAVING COUNT(*) = 1 
ORDER BY value1 

コードは私に2つのテーブル間のすべての違いを示します。したがって、TABLE_AではvalueXが存在しますが、TABLE_Bでは存在しない場合はvalueXが表示され、その逆もあります。

要するに、行の2つの値に基づいてTABLE_Bに存在しないTABLE_Aからすべての行を取得したいとします。

誰かが助けてくれることを祈っています。

+0

一致する列にインデックスを作成しましたか? – Roy

+0

ご返信ありがとうございます。 MySQLのクエリには比較的新しいので、あなたが何を意味するのかよくわかりません。インデックスを作成するにはどうすればいいですか? –

+0

PHPは言語であり、mysqlのアドオンではありません –

答えて

0

いくつかの試行錯誤の末、私は2番目のコードブロックを改良しました。私は結果をさらにフィルタリングするために私のテーブルに追加フィールドがあることに気づいた。

SELECT date, value1, value2 
FROM (
    SELECT date, value1, value2 
    FROM (
     SELECT ta.date, ta.value1, ta.value2 
     FROM table_1 ta 
     UNION ALL 
     SELECT tb.date, tb.value1, tb.value2 
     FROM table_2 tb 
    ) filter 
    GROUP BY value1, value2 
    HAVING COUNT(*) = 1 
) result 
WHERE date='YYYY-MM-DD' 

このコードは、結果を4秒以内でフィルタリングします。

とにかく、ありがとうございました。

3

なぜ結合を使用しないのですか?

/* Create a table called NAMES */ 
CREATE TABLE NAMES(Id integer PRIMARY KEY, Name text, LastName text); 
CREATE TABLE OTHERNAMES(Id integer PRIMARY KEY, Name text, LastName text); 

/* Create few records in this table */ 
INSERT INTO NAMES VALUES(1,'Tom','Riddle'); 
INSERT INTO NAMES VALUES(2,'Lucy','I love'); 
INSERT INTO NAMES VALUES(3,'Frank','Frankly'); 
INSERT INTO NAMES VALUES(4,'Jane','Austen'); 
INSERT INTO NAMES VALUES(5,'Robert','Downey'); 

INSERT INTO OTHERNAMES VALUES(2,'Lucy','I love'); 
INSERT INTO OTHERNAMES VALUES(3,'Frank','Frankly'); 
INSERT INTO OTHERNAMES VALUES(4,'Jane','Austen'); 
INSERT INTO OTHERNAMES VALUES(5,'Robert','Downey'); 

select * from NAMES 
LEFT JOIN OTHERNAMES on 
    NAMES.Name = OTHERNAMES.Name 
    AND Names.LastName = OTHERNAMES.LastName 
where OTHERNAMES.id is null 

あなたが右のテーブルに存在しないLEFT JOINアイテムはどこでフィルタリングすることができ、ヌルエントリに置き換えられます使用している場合は、オンラインhttp://sqlfiddle.com/#!9/640c53/1

それを参照してください。

あなたの60.000データベースの効率はわかりませんが、これは通常、私のトリックです。

+0

お返事ありがとうございます。残念なことに、このクエリは時間がかかります。私は20,000行を比較しただけで約5〜10分走っていました。だから、完了するまでにはかなり時間がかかりました。 –

+1

比較のために使用している列にインデックスを作成しましたか? 20.000行は何もありません。私は毎日100,000セット以上のジョインを行い、ミリ秒で完了します。適切なインデックスが重要です。それ以外の場合、データベースエンジンの最適化に問題があります。 – Tschallacka

+0

主な質問の下の返信で述べたように、私はMySQLのクエリに比較的新しいです。しかし、私は選択している列のインデックスを作成しようとしました。そして、今すぐjoinクエリが2番目の下で実行されます!私自身の答えで言ったように、私はUNIONクエリで解決策を見つけましたが、別の検索のためにJOINクエリを使用していて、速く実行しています!助けてくれてありがとう、本当にそれを感謝します。 –

関連する問題