- ベストアンサー
MySQLで複数のSELECT文を1文にまとめる方法と負荷軽減のためのインデックス作成について
- MySQLで複数のSELECT文を1文にまとめる方法と負荷軽減のためのインデックス作成について解説します。
- 具体的な例を交えながら、IDと教科を指定したときに、名前と順位、およびレコード数を得る方法を紹介します。
- また、サーバーの負荷を減らすためにインデックスの作成についても考察します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
教科中の順位とその教科のレコード数を1回で取得するなら、下記の様にSELECT句内のサブクエリを一つ追加すれば良いだけです。 ---------------------------------------- SELECT Name, Kyouka, Score, (SELECT COUNT(*) + 1 FROM table1 b WHERE b.Score > a.Score AND a.Kyouka = b.Kyouka) AS rank, (SELECT COUNT(*) FROM table1 c WHERE a.Kyouka = c.Kyouka) AS count FROM table1 a WHERE ID = '10001' ORDER BY Kyouka, Score DESC; ---------------------------------------- また、上記の様に教科をサブクエリ内の結合条件で絞り込んでやると、WHERE句の条件を変えるだけで色々な絞込みが可能です。 例) [国語の全データを取得] ------------- SELECT Name, Kyouka, Score, (SELECT COUNT(*) + 1 FROM table1 b WHERE b.Score > a.Score AND a.Kyouka = b.Kyouka) AS rank, (SELECT COUNT(*) FROM table1 c WHERE a.Kyouka = c.Kyouka) AS count FROM table1 a WHERE Kyouka = '国語' ORDER BY Kyouka, Score DESC; ---------------------------------------- 性能が気になるようでしたら、下記の様にカウントはFROM句内のサブクエリで取得した方がよいかも知れません。 ---------------------------------------- SELECT Name, Kyouka, Score, (SELECT COUNT(*) + 1 FROM table1 b WHERE b.Score > a.Score AND a.Kyouka = b.Kyouka) AS rank, c.count FROM table1 a INNER JOIN (SELECT Kyouka, COUNT(*) AS count FROM table1 GROUP BY Kyouka) c USING(Kyouka) ORDER BY Kyouka, Score DESC; ---------------------------------------- なお、他の方も指摘されている通り、Kyoukaカラムにもインデックスを張ったほうが良いと思います。
その他の回答 (2)
- Python864
- ベストアンサー率13% (4/29)
負荷を減らすという事なら、この場合SQLを1回にするよりも、 (2)の教科のレコード数は、ID別に毎回取得する必要は無さそうに思いますので、 その負荷が無駄になるという理由から、 (2)教科のレコード数は複数のIDに対して一回だけ取得し、 プログラムの変数等に格納しておくほうが効率的だと思います。 いずれにしてもKyoukaにインデックスを作成したほうがよいです。
お礼
大変参考になりました。 ご回答ありがとうございました。
- Bnbnbnta101
- ベストアンサー率7% (41/516)
具体的に大量のデータがどのくらいあるのかわからないのでなんともいえないですが。 教科にはインデックスはったほうが良いです。 2は教科でグループバイして、教科毎のカウントを取得。 その結果を1のテーブル1と結合すれば一度のセレクトで取得できるでしょう。
お礼
参考にさせていただきます。 ご回答ありがとうございました。
お礼
とても分かりやすいご回答をいただけて大変感謝いたしております。 ありがとうございました。