• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:もうちょっと賢いSELECT文が書けないものでしょうか)

賢いSELECT文の書き方

このQ&Aのポイント
  • 賢いSELECT文の書き方について知りたいです。現在、効率の悪いSELECT文しか書けずに困っています。
  • テーブルsoftware_tableから、name列が「oracle」であり、version値が最大のidを取得する方法について教えてください。
  • 副問い合わせやソートを使わずにSELECT文を効率よく実行する方法はあるのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
noname#249320
noname#249320
回答No.2

数十万件だと毎回実行するにはなかなか厳しい感じですね。 状況から察するに, name にインデックスを張ってもあまり有効に働かないみたいですね。 アプリケーションを考慮して, name と versionの最大値 の組み合わせの抽出が頻繁に行われるようでしたら, name と versionの最大値の二つの列を持つ参照用のテーブルを作成して, そこから参照するようにしてはどうでしょうか。 software_table に INSERT/UPDATE/DELETE が発生したら, 上記のテーブルをトリガを利用して書き換えればよいと思います。 # もちろんプログラム側で対応しても構いません name と versionの最大値の組み合わせの参照がそれほど発生せず, アプリケーション的にも多少時間がかかるのが許されるならば, 副問い合わせやソートのやり方でもよいと思いますよ。

strangechameleon
質問者

お礼

 なるほどと思いました。で、nameとversionの最大値の組み合わせでの参照は頻繁に行われるため、試しに参照用のテーブルを作成して実行計画を見てみました。  のですが、、速度を計測してみたところレスポンスは副問い合わせを使ったときの方が早いようです(レコード3万件で実験)。  おそらくテーブルの結合に時間がかかってしまってることが原因ではないかと考えています。  しかし今回はたまたまテーブル結合が無いケースでしたが、もともとのSELECT文でテーブル結合をする必要がある場合には、参照用のテーブルを作ったほうが早いかもしれませんね。 何度もアドバイスをくださってありがとうございます。もはや改善は無理っぽい感じですが、重要な部分なのでもう一日だけ頑張ってみようと思います^^;

すると、全ての回答が全文表示されます。

その他の回答 (1)

noname#249320
noname#249320
回答No.1

基本的には副問い合わせやソートはコストのかかる処理です。 ただ, それはデータ件数が数十万, 数百万にもなった場合に実際に体感できる負荷として顕在化してきます。 software_table に格納されるデータ量の見積もりはどのくらいを想定しているのでしょうか? 格納されて高々数千件というレベルであれば, 書かれてある副問い合わせやソートを使っても全く問題ないと思います。 また, name属性で検索結果がかなり絞り込めるのであれば, その後に MAX関数で最大値を求めようがソートで並び替えをしようがコストはほとんどかかりません。 副問い合わせやソートは必ずしも悪というわけではなく, 状況によって使い分ければよいと思います。 ちなみに GROUP BY を使って以下のようにもかけます。 が, 特に効率がいいということはありません ^^; SELECT name, MAX(version) FROM software_table WHERE name = 'oracle' GROUP BY name;

strangechameleon
質問者

お礼

お返事ありがとうございます。 お返事をいただいて真っ先に思いましたのは、「SELECT文を書く場合、絞り込みの順番を意識することがすごく重要だ」ということです。絞込みやすい順にwhere句を記述していくとそれだけでパフォーマンスが上がるんですね。DBエンジニアとしては当たり前の知識なのでしょうが、勉強になりました。 ただ「nameの絞込み自体のコストが大きい」ことは確かで、それが今回のケースでは問題になりそうだと感じました。メインの文と副問い合わせ文の両方でnameで絞込みをかけなければいけなくなっているので。。 なお、格納されるデータ量ですが、詳しくはわかりませんが数十万件くらいにはなる予定です。 お返事ありがとうございました^-^

すると、全ての回答が全文表示されます。

専門家に質問してみよう