2016-07-29 17 views
2

1千万を超える行がある表で問合せを実行する必要があります。 テーブル構造は複数の列の索引付け

user(varchar 100), 
played(int 11), 
won(int 11), 
lost(int 11), 
drawn(int 11), 
user1(varchar 30), 
user2(varchar 30). 


Where 
User - primary key 
user1 - index 
user2 - index 

MySQLデータベースエンジンはMyISAMテーブルです。

私の問題は - 私は以下のクエリを実行すると17秒以上かかる。

SELECT * FROM h2hstats 
WHERE (won+lost+drawn) > 5 
    AND (user1 = '717054941' OR user2 = '717054941') 

この実行時間を短縮するにはどうすればよいですか?

(won + lost + drawn)列で別のインデックスを作成しますか?

+0

ハズレを、あなたがそれらを検索しませんので。条件が満たされると、データにアクセスできます。したがって、user1とuser2の適切なインデックスに依存します。また、数値のみを含む列に数値フィールド型(INTEGERまたはBIGINT)を使用すると、パフォーマンスが向上します。 – syck

+1

このようにする前にこのようなことをしたことはありませんでしたが、これはおそらく次のようになります。 AND 717054941 IN(user1、user2) – Jeff

+0

win + last + drawn ..http://dev.mysql.com/doc/refman/5.7 /en/generated-column-index-optimizations.html..さらに、2つの別々のインデックス(user1、user2)をどのように使用できるか分かりません。 – TheGameiswar

答えて

2

最初に、ユーザー列が数字の場合、定数には一重引用符を使用しないでください。これはオプティマイザを混乱させる可能性があります。これはおそらくあなたのクエリ(私のSQLはORのためのインデックスを使用するのは苦労します)を助けませんが、試してみる価値があります。

次に、としてクエリを書き直す考えてみます。

SELECT * 
FROM h2hstats 
WHERE (won + lost + drawn) > 5 AND user1 = 717054941 
UNION ALL 
SELECT * 
FROM h2hstats 
WHERE (won + lost + drawn) > 5 AND user2 = 717054941 ; 

MySQLは間違いなくサブクエリごとにインデックスを使用します。これにより、パフォーマンスが向上します。

(注:このバージョンでは、これが可能であるならば、あなたはUNION ALLではなくUNIONを使用する場合があります<>user2user1ことを前提としています。)

関連する問題