データ量が10万件を超えてきてからだんだん処理が遅くなり、15万件になったころには3秒ほど処理速度が遅くなってしまいました。
トップページで行っている処理なので、この遅さは大きな問題になっています。
しかし、自分で各項目にインデックスをつけたり、クエリを変更したりしても改善されることがなかったので、皆さんのお力をお借りしたいです。
各テーブルの設計と、クエリを記載しますので、どうかアドバイスをお願いします。
※サイトの特定回避のため、ここでは内容を変えて説明します。クエリ自体はほぼ一緒です。
MySQLバージョン:5.6.22
t_syumi[InnoDB] 趣味テーブル
syumi_id(autoincrement),syumi_name データ数約2000件 ※syumi_idがプライマリキー
1,スポーツ
2,読書
3,映画鑑賞
4,音楽
…………等
t_user[InnoDB] ユーザーテーブル データ数約6000件
user_id(autoincrement),user_name ※user_idがプライマリキー
1,田中一郎
2,山口明子
3,佐藤俊哉
4,鈴木太郎
…………等
**t_setting[InnoDB] 趣味設定テーブル ** データ数約6000件
※一人で複数の趣味を持っている場合もあります
set_id(autoincrement),user_id,syumi_id ※set_idがプライマリキー,user_id,syumi_idに複合ユニークキー制約があります
1,1,4
2,1,2
3,2,1
4,3,2
…………等
t_petlist[InnoDB] ユーザーの飼っているペットの名前テーブル データ数約150000件
※一人で複数のペットを飼っている場合もあるため、一人で複数登録されている場合もあります
pet_id(autoincrement),user_id,pet_name ※pet_idがプライマリキー,user_id,pet_nameに複合ユニークキー制約があります
1,1,ポチ
2,1,ハチ
3,2,まろ
4,3,ジロー
…………等
使用するテーブルは以上です。
クエリは、**「趣味別で飼っているペットの名前の種類数を表示」**です。
SQL
1SELECT syumi_id,syumi_name,COUNT(DISTINCT(pet_name)) AS cnt 2FROM t_petlist 3INNER JOIN t_setting ON t_petlist.user_id = t_setting.user_id 4INNER JOIN t_syumi ON t_syumi.syumi_id = t_setting.syumi_id 5GROUP BY syumi_id 6ORDER BY cnt DESC
各カラムは、左から「趣味ID」「趣味の名前」「その趣味の人が飼っているペットに名付けた名前の種類数」になります。
結果は
1,スポーツ,5431
2,読書,4480
4,音楽,4398
...といった結果が出力されます。
このクエリが約3秒ほどかかってしまいます。
目標は1秒を切りたいと考えています。
重くしている部分は、COUNT(DISTINCT(pet_id))で、DISTINCTを外すと0.5秒もかからないほど早くなります。
ただ、今回カウントしたいのは、「その趣味の人が飼っているペットに名付けた名前の種類数」なので、
スポーツが趣味の人で、その中の5人がペットに「ポチ」と名付けた場合は、その重複は除かなくてはいけません。
いろいろインデックスをつけたり外したり試してみましたが、どれも大体3秒ほどかかってしまいます。
既に大量のデータが入っている上、なるべく早めの対応が必要となりますので、テーブル設計から1から作り直すのは厳しいです。
とりあえずは、「インデックス操作」「クエリの変更」など、大きな変更を加えなくてもよい範囲でどなたかご教示お願いしたいです。もちろん、テーブル設計のアドバイス等も頂けたらうれしいです。
何かご不明点があればお気軽に聞いてください。どなたかアドバイスお願い致します。

回答5件
あなたの回答
tips
プレビュー