2012-04-07 2 views
0

TabellenschemaOptimierung dieses MySQL Query

Für die beiden Tabellen sind die CREATE-Abfragen unten angegeben:

Tabelle 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; 

Tabelle2: (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; 

Ziel:

ein file_path Da F und es ist dir_path String D, muss ich alle diese Dateinamen finden, die in mindestens einem Hash haben die Satz von Hashes F, aber haben ihre Verzeichnisnamen nicht als D. Wenn eine Datei F1 mehrere Hashes teilt mit F, dann sollte es so oft wiederholt werden.

Beachten Sie, dass die Spalte file_path_key in Tabelle1 und die Spalte hash_key in Tabelle2 indiziert sind.

In diesem speziellen Fall, Tabelle 1 hat rund 350.000 Einträge und Table2 hat 31.167.119 Einträge, die langsam meine aktuelle Abfrage macht:

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 

Wie kann ich diese Abfrage beschleunigen?

+0

Ist Ihre Frage "Wie kann ich meine aktuelle Anfrage optimieren?"? Sagen Sie uns auf jeden Fall, was Sie eigentlich lösen wollen. – Bojangles

+0

Ja, JamWaffles, ich möchte es beschleunigen! – user1318956

Antwort

0

Ich verstehe nicht, was der Zweck der temp Tabelle ist, aber denken Sie daran, dass solche Tabelle, erstellt mit CREATE .. SELECT, hat keine Indizes. So zumindest beheben diese Aussage zu

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

Ansonsten ist der andere SELECT führt voll mit temp kommen, so könnte es sehr langsam sein.

Ich würde auch vorschlagen, einen numerischen Primärschlüssel (INT, BIGINT) in Tabelle1 zu verwenden und es von Table2 anstatt von der Textspalte zu verweisen. ZB:

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; 

Abfragen der beiden Tabellen verbinden kann viel schneller sein, wenn Integer-Spalten verwendet werden, in Joinvergleichselement und nicht als Text Einsen.

+0

Mushu, würde das erfordern, dass ich Indizes wie zuvor hinzufüge? – user1318956