2011-01-16 14 views
2

私は3行で、events、MySQLのInnoDBのテーブルを持っている:MySQLクエリはインデックスに時間がかかりますか?

select a.* from events a, events b 
where a.event_id != b.event_id and 
     a.start < b.end and 
     b.start < a.end 

テーブル:別のイベントと競合することを私はいくつかの範囲内のすべてのイベントを取得するための単純なクエリを書かれている

event_id ---> int 
start  ---> long 
end  ---> long 

〜10Kの行があり、実行に約2秒かかりました。パフォーマンスを向上させるためにテーブルを微調整しようとしている間に、startendカラムにインデックスを追加しました。なんらかの理由で、これは劇的にのパフォーマンスを低下させた5xのファクタで減少させました。誰もが知っている、または任意のアイデアを持って、なぜこれらのインデックスを追加するパフォーマンス悪い傷つけるだろうか?

答えて

1

MySQLは関連する列を調べ、索引がクエリを改善するのに役立つと誤解しています。しかし、問題は、インデックスが開始部分を解決するが、それ自体が高価な操作であるa.event_id!= b.event_idを解決するためにレコードIDに解決する必要があることです。

インデックスを持たないと、クロスジョインとフィルタが強制的に実行されますが、多数の一時レコードが表示されることがありますが、これははるかに簡単で簡単な実装です。

クエリがaまたはbの開始範囲に対してある範囲でバインドされている場合、および/またはテーブルが10kより大きい場合は、非常に異なる画像になる可能性があります。

インデックスを保持する必要がある場合(あなたはこのことができます知っていれば)、あなたはインデックスを無視して、特定のクエリを強制することができます:インデックスはindex1と命名されたと仮定すると、

select a.* 
from events a ignore index (index1) 
cross join events b ignore index (index1) 
where a.event_id != b.event_id and 
     a.start < b.end and 
     b.start < a.end 

。いずれの場合でも、MySQLが結果を収集する方法を示すためにクエリの前に "EXPLAIN"を追加することで、MySQLが何をしているのかを常に知ることは役に立ちます(インデックスなし、インデックス付き、インデックスあり、無視されます)

+0

私はインデックスを保持することができます(彼らは他のクエリを助けるが、クロス結合とフィルタを実行するようなクエリを構造化する方法はありますか? – JaredC

関連する問題