2012-03-06 14 views
0

表スキーマ二つのテーブルについて最適化されたSQLクエリ

、CREATEクエリを以下に示す:

表1:(file_path_key、dir_path_key)

CREATE TABLE表1を(file_path_key varchar(500)、dir_path_key varchar(500)、主キー(file_path_key))エンジン= innodb;

例、file_path_key = /home/playstation/a.txt
dir_path_key = /ホーム/プレイステーション/

表2:(file_path_key、hash_key)

テーブルを作成しますテーブル2(file_path_key varchar(500)not null、hash_key )bigint(20)NULL以外の外部キー(file_path_key)の参照 テーブル1(file_path_key)on upd削除カスケードでカスケードを行った) エンジン= innodb;客観

:この特定のケースで

Given a hash value *H* and a directory string *D*, I need to find all those 
hashes which equal to *H* from Table2, such that, the corresponding file entry 
doesn't have *D* as it's directory. 

は、表1には、周りに40,000のエントリを持っており、表2は、私の現在のクエリが本当に遅いなり5,000,000エントリを持っています。 s1が参加として

表1から別個s1.file_path_keyを選択S2としてs1.file_path_key = s2.file_path_keyとs1.dir_path_keyに(*ここhash_key表2 = Hから選択)= D!。

+0

確かにあなたのキーの(潜在的な)サイズ助けにはならない。潜在的な鍵の範囲が必要ではないように見えます。参加する自動生成の主キーに切り替えることを検討しますか?これはあなたのテーブルのサイズをかなり減らすはずです。一つは、 'file_path_key'が単に' file'に変わる可能性があるということです(これは潜在的に不一致を減らすでしょう)。再帰的なCTEをサポートするRDBMSを使用していないのは残念です。これらは、フォルダ構造に対して完全に機能します。 –

答えて

1

サブ選択が本当にあります不必要にクエリを減速させます。

これを削除して単純な結合で置き換えて、結合に関連しないすべての条件をWHERE句にプッシュします。

また、あなたはTable1.dir_path_keyとTable2.hash_key列に索引を追加する必要があります

ALTER TABLE Table1 
    ADD INDEX dir_path_key dir_path_key(255); 

ALTER TABLE Table2 
    ADD INDEX hash_key (hash_key); 

は、クエリのためにこのような何かを試してみてください:

select distinct s1.file_path_key 
from Table1 as s1 
join Table2 as s2 on s1.file_path_key = s2.file_path_key 
where s1.dir_path_key !=D 
and s2.hash_key =H; 
+0

もちろん、これを試してみます。列にインデックスを追加するにはどうしたらいいですか? – Gooner

+0

インデックスを作成するためのサンプルDDLを追加しました。これは、テーブルを数分間ロックするので、実稼働データベースでは実行しないでください。 –

+0

うわー、テーブルは私のユースケースでいっぱいになると更新されない。それは問題ではないはずですか? – Gooner

1

私は最初の一時テーブルに表2からエントリを選択することをお勧めしたい:

SELECT * FROM Table2 INTO #Temp WHERE hash_key = H 

次に、あなたのSELECT文で一時テーブルに参加:

select distinct s1.file_path_key from Table1 as s1 join #Temp as s2 on s1.file_path_key = s2.file_path_key and s1.dir_path_key !=D; 
+0

これはクエリの実行時間に影響しますか? – Gooner

+0

私はこれを過去に実践したとき、通常はかなりの差があることに気付きました。 – aaroncatlin

+0

もちろん、これを試してみます。 – Gooner