0

テーブルスキーマ

2つのテーブルについて、CREATEクエリを以下に示します。

表1: (file_path_key、dir_path_key)

create table Table1(
             file_path_key varchar(500), 
             dir_path_key varchar(500), 
             primary key(file_path_key)) 
engine = innodb;

表2 :(file_path_key、hash_key)

create table Table2(
             file_path_key varchar(500) not null, 
             hash_key bigint(20) not null, 
             foreign key (file_path_key) references Table1(file_path_key) on update cascade on delete cascade)
engine = innodb;

目的

file_path Fとそのdir_path文字列Dが与えられた場合、Fのハッシュのセットに少なくとも1つのハッシュがあるが、ディレクトリ名がDではないすべてのファイル名を見つける必要があります。ファイルF1がFと複数のハッシュを共有している場合は、それを何度も繰り返す必要があります。

表1のfile_path_key列と表2のhash_key列にインデックスが付けられていることに注意してください。

この特定のケースでは、Table1には約350,000エントリがあり、Table2には31,167,119エントリがあるため、現在のクエリは遅くなります。

create table temp 
        as select hash_key from Table2 
        where file_path_key = F;

select s1.file_path_key 
        from Table1 as s1 
        join Table2 as s2 
        on s1.file_path_key join 
        temp on temp.hash_key = s2.hash_key 
        where s1.dir_path_key != D

このクエリを高速化するにはどうすればよいですか?

4

1 に答える 1

0

tableの目的がわかりませんがtemp、CREATE .. SELECT で作成されたそのようなテーブルにはインデックスがないことを覚えておいてください。したがって、少なくともそのステートメントを次のように修正してください

CREATE TABLE temp (INDEX(hash_key)) ENGINE=InnoDB AS 
SELECT hash_key FROM Table2 WHERE file_path_key = F;

そうしないと、他の SELECT が との完全な結合を実行するtempため、非常に遅くなる可能性があります。

また、Table1 で数値の主キー (INT、BIGINT) を使用し、テキスト列ではなく Table2 から参照することをお勧めします。例えば:

create table Table1(
             id int not null auto_increment primary key,
             file_path_key varchar(500), 
             dir_path_key varchar(500), 
             unique key(file_path_key)) 
engine = innodb;

create table Table2(
             file_id int not null, 
             hash_key bigint(20) not null, 
             foreign key (file_id) references Table1(id) 
            on update cascade on delete cascade) engine = innodb;

2 つのテーブルを結合するクエリは、テキスト列ではなく結合述語で整数列が使用されている場合、はるかに高速になる可能性があります。

于 2012-04-07T12:22:15.770 に答える