2010-11-19 29 views
0

は、次の2つのクエリを考えてみますWHERE追加:句は、クエリが本当に遅い

select a.*, c.* 
from account a 
join customer c on a.customer_id = c.id 
join import i on a.import_id = i.id 
join import_bundle ib on i.import_bundle_id = ib.id 

select a.*, c.* 
from account a 
join customer c on a.customer_id = c.id 
join import i on a.import_id = i.id 
join import_bundle ib on i.import_bundle_id = ib.id 
where ib.id = 8 

最初のクエリが高速であり、二つ目は超遅いです。どんな考え?私はインデックスなどが必要だと思っていますが、インデックスの仕組みは分かりません。私はMySQLを使用しています。

は、ここで私は2番目のクエリにEXPLAINをすれば何が起こるかです:

id select_type  table type possible_keys key  key_len  ref  rows Extra 
1 SIMPLE ib const PRIMARY  PRIMARY  8 const 1 Using index 
1 SIMPLE c ALL  PRIMARY   144858 
1 SIMPLE a ref  fk_account_customer_id,fk_account_import_id  fk_account_customer_id 8 mcif.c.id 2 
1 SIMPLE i eq_ref PRIMARY,import_bundle_id PRIMARY  8 mcif.a.import_id 1 Using where 

私も、それを解釈する方法がわかりません。

編集:

select a.*, 
     c.* 
    from account a 
    join customer c on a.customer_id = c.id 
    join (select id, 
       import_bundle_id 
      from import 
     where import_bundle_id = 8) i on a.import_id = i.id 
    join import_bundle ib on i.import_bundle_id = ib.id 

何もしませんでしたimport_bundle.idにインデックスを追加する:これは私が使用して終了するものです。

+0

クエリプランはどのように見えますか?インデックスはib.idをカバーしていますか? –

+0

「クエリプランはどのように見えますか?」とはどういう意味ですか? –

+0

場合によっては、物事が見えない場合もあります。 2つのクエリをどのように比較しましたか? _first_レコードが取得された時刻または_last_レコードを調べましたか?後者は測定する必要がありますが、SQLクライアントアプリケーションから作業している場合は前者を見るだけで簡単です。 – Axn

答えて

1
  • パフォーマンスに関して、クエリでは、実際に。*とc。*が必要ですか?

  • したがって、索引の使用は十分に改善されません。私はmysqlに精通していないが、このようなサブクエリで結合を試みることができますか?

 
    select a.*, c.* 
    from account a 
    join customer c on a.customer_id = c.id 
    join 
    ( 
     SELECT id, import_bundle_id FROM import WHERE id = 8 
    ) as i on a.import_id = i.id 
    join import_bundle ib on i.import_bundle_id = ib.id 
    where ib.id = 8 
  • おそらく、最良の指標は以下のとおりです。import.import_bundle_idのインデックスとimport_bundle.id上の別のインデックス。
+0

注:このクエリを実際に動作させるには、このクエリを少し編集しなければなりませんでした( 'id = 8'は' where import_bundle_id = 8'でなければなりません)。インデックスは何も変わらなかった。 –

1

後者のクエリ軍のMySQLをどのように機能するかをここで

、 MySQLはそれらすべてをチェックする必要はなく、対応するレコードをすばやく見つけることができます。

データベースのインデックスは、すべてのページを調べるのではなく、背中のインデックスに移動して、探しているページ番号を見つけてそこにまっすぐに進みます。

+0

ええ、私は 'CREATE INDEX id_index ON import_bundle(id)'を実行しましたが、速度には目に見える影響はありませんでした。私はそれを間違っているのですか? –

+0

@ Jason Swett必ずしも、索引は結果セットを制限するプロセスをスピードアップしますが、まだまだ時間がかかります。 – Orbling

+0

@ Jason Swettあなたのクエリプランから、import_bundle.idがすでにそのテーブルのプライマリキーであることがわかりましたか?プライマリキーは一意のインデックス自体であるため、追加のインデックスを追加することで速度に差は生じません。これは、プランに従ってWHERE句のPRIMARYインデックスを使用します。 – Orbling

0

私は特にmysqlに精通していませんが、ib.idのインデックスがほぼ確実に役立ちます。 JOIN句またはWHERE句で使用するフィールドは、通常、索引付けする必要があります。また、ib.idの代わりにi.import_bundle_idをフィルタリングし、それが役立つかどうかを確認することもできます。

一般的に、インデックスは情報をより速く見つけるのに役立ちます。適切なものを見つけるためにデータベース全体に広がったすべてのアイテムを見なければならないのではなく、ハッシュテーブルなどの方法を使って見た目を絞って、正確なレコードに絞り込むことができます。 Wikipedia explains itよりもはるかに優れています。 :)

0

他の回答は正しい方向に指している限り、ib.idです。ただし、ib.idは主キー(PK)のように見えます。データベースにPKとして設定されていますか?そうであれば、それは自動的にPKであるためにインデックスを取得するはずです。それがPKとして設定されておらず、実際にはであるべき列である場合、パフォーマンスだけでなくデータベースに多くの問題があるでしょう。

つまり、ib.idを主キーにする必要がある場合は、それを1にしてください。自動的にインデックスが作成されるため、パフォーマンスが向上するはずです(別途インデックスを追加する心配もありません)。

+0

これはPKです。なんらかの理由で、Stack Overflowのコメントは少なくとも一定の長さでなければならないので、私はここでより多くの情報を入力しています。 –

関連する問題