質問

JDBCを使用する場合、次のような構造に遭遇することがよくあります

ResultSet rs = ps.executeQuery();
while (rs.next()) {
    int id = rs.getInt(1);
    // Some other actions
}

列の値を取得するためにラベルを使用しない理由を自分自身(およびコードの作成者も)に尋ねました:

int id = rs.getInt("CUSTOMER_ID");

私が聞いた最高の説明は、パフォーマンスに関するものです。しかし、実際には、処理が非常に高速になりますか?信じられませんが、測定を行ったことはありません。私の意見では、ラベルによる取得が少し遅くなるとしても、読みやすさと柔軟性が向上します。
だから誰かが私に列ラベルではなく列インデックスによって列値を取得することを避けることの良い説明を与えることができますか?両方のアプローチの長所と短所は何ですか(特定のDBMSについて)。

役に立ちましたか?

解決

デフォルトでは、文字列ラベルを使用する必要があります。

長所:

  • 列の順序の独立性
  • 読みやすさ/保守性の向上

短所:

  • 列名を制御することはできません(ストアドプロシージャによるアクセス)

どちらを選択しますか

ints?

  

int i = 1;
   customerId = resultSet.getInt(i ++);
   customerName = resultSet.getString(i ++);
   customerAddress = resultSet.getString(i ++);

or Strings?

  

customerId = resultSet.getInt(" customer_id");
   customerName = resultSet.getString(" customer_name");
   customerAddress = resultSet.getString(" customer_address");

そして、位置1に新しい列が挿入されたらどうなるでしょうかどのコードが好きですか?または、列の順序が変更された場合、どのコードバージョンを変更する必要がありますか?

だからこそ、文字列ラベルをデフォルトで使用すべきです。

他のヒント

警告:ここで大騒ぎします。これは私を夢中にさせるからです。

99%*は、人々が漠然としたアイデアを持っていることが物事を「より良く」するという、ばかげたマイクロ最適化です。これは、非常にタイトでビジーなループで何百万ものSQL結果を常に確認しなければならないという事実を完全に無視します。それを行っていないすべての人にとって、列のインデックス付けのバグの維持、更新、修正にかかる開発者の時間コストは、無限に性能が悪いアプリケーションのハードウェアの増分コストよりもはるかに大きくなります。

このような最適化をコーディングしないでください。それを保守する人のためのコード。次に、観察、測定、分析、最適化を行います。もう一度観察し、再度測定し、再度分析し、再度最適化します。

最適化は開発の最終段階であり、最初の段階ではありません。

*図は構成されています。

それでもなお答えは受け入れられましたが、ここにはまだ紹介していない追加情報と個人的な経験があります。

一般的に、可能であれば、列名(リテラルではなく定数が推奨されます)を使用します。これはどちらも明確であり、保守が容易であり、将来の変更によってコードが破損する可能性は低くなります。

ただし、列インデックスの使用があります。場合によっては、これらはより高速ですが、名前*の上記の理由を無効にするほど十分ではありません。これらは、 ResultSet を扱うツールや一般的なメソッドを開発するときに非常に貴重です。最後に、列に名前がない(名前のない集約など)か、名前が重複しているために両方を参照する簡単な方法がないため、インデックスが必要になる場合があります。

* JDBCドライバーをいくつか作成し、いくつかのオープンソースドライバーの内部を調べましたが、内部では列インデックスを使用して結果列を参照しています。私が扱ったすべての場合において、内部ドライバーは最初に列名をインデックスにマップします。したがって、これらのすべての場合において、列名は常により長くかかることが簡単にわかります。ただし、これはすべてのドライバーに当てはまるわけではありません。

Javaドキュメントから:

  

ResultSetインターフェースは、現在の行から列の値を取得するためのgetterメソッド(getBoolean、getLongなど)を提供します。値は、列のインデックス番号または列の名前を使用して取得できます。一般に、列インデックスを使用する方が効率的です。列には1から番号が付けられます。移植性を最大にするには、各行内の結果セットの列を左から右の順序で読み取り、各列を1回だけ読み取ります。

もちろん、各メソッド(名前付きまたはインデックス付き)には場所があります。名前付き列がデフォルトであることに同意します。ただし、膨大な数のループが必要な場合、およびSELECTステートメントがコード(またはクラス)の同じセクションで定義および維持されている場合、インデックスは大丈夫です-選択されている列だけでなく、選択することをお勧めします" SELECT * FROM ..."。テーブルを変更するとコードが破損するためです。

もちろん、列名を使用すると読みやすくなり、メンテナンスが容易になります。ただし、列名の使用には裏返しがあります。ご存知のように、SQLは同じ名前の複数の列名を許可します。resultSetのgetterメソッドに入力した列名が、実際にアクセスする列名を指している保証はありません。理論的には、列名の代わりにインデックス番号を使用することが推奨されますが、読みやすさが低下します...

ありがとう

ラベルの使用はパフォーマンスに大きな影響を与えないと思います。しかし、 String を使用しない別の理由があります。または、 int s、そのことについて。

定数の使用を検討してください。 int 定数を使用すると、コードが読みやすくなりますが、エラーが発生する可能性も低くなります。

より読みやすいことに加えて、定数はラベル名にタイプミスをすることを防ぎます-そうするとコンパイラはエラーを投げます。そして、どんな価値のあるIDEでもそれを取り上げます。これは、 String sまたは ints を使用する場合には当てはまりません。

この正確な件名について、Oracleデータベースでパフォーマンスプロファイリングを行いました。コードには、多数の列と膨大な数の行を持つResultSetがあります。 20秒(!)のうち、メソッドoracle.jdbc.driver.ScrollableResultSet.findColumn(String name)の実行にリクエストにかかる時間は約4秒です。

明らかに全体的な設計に問題がありますが、列名の代わりにインデックスを使用すると、おそらく4秒かかります。

あなたは両方の長所を持つことができます!列名を使用する保守性とセキュリティを備えたインデックスの使用速度。

最初-結果セットをループする場合を除き、列名のみを使用します。

  1. アクセスする列ごとに1つずつ、整数変数のセットを定義します。変数の名前には、列の名前を含めることができます。 iLast_Name。

  2. 結果セットループが列メタデータを反復処理する前に、各整数変数の値を対応する列名の列インデックスに設定します。 「Last_Name」列のインデックスが3の場合、「iLast_Name」の値を3に設定します。

  3. 結果セットのループでは、GET / SETメソッドで整数変数名を使用します。変数名は、アクセスされている実際の列名に関する開発者/保守者への視覚的な手がかりですが、値は列インデックスであり、最高のパフォーマンスを提供します。

注:最初のマッピング(つまり、列名からインデックスへのマッピング)は、ループ内のすべてのレコードと列ではなく、ループの前に1回だけ実行されます。

JDBCドライバーは、列のインデックス検索を処理します。そのため、ドライバーがルックアップ(通常はハッシュマップで)を行うたびに列名で値を抽出し、列名の対応するインデックスを確認します。

パフォーマンスは、どちらかのアプローチを選択することを強いるものではないという以前の回答に同意します。代わりに、次のことを検討することをお勧めします。

  • コードの読みやすさ:コードラベルを読むすべての開発者にとって、インデックスよりもはるかに意味があります。
  • メンテナンス:SQLクエリとそのメンテナンス方法を考えてください。 SQLクエリを修正/改善/リファクタリングした後、あなたのケースで起こりそうなこと:抽出された列の順序の変更または結果列名の変更。 (結果セットに新しい列を追加/削除した結果として)抽出された列の順序を変更すると、発生する可能性が高くなります。
  • カプセル化:選択した方法にもかかわらず、SQLクエリを実行するコードを分離し、同じコンポーネントで結果セットを解析し、このコンポーネントのみに列名とインデックスへのマッピングを認識させます(決定した場合)それらを使用する)。

インデックスの使用は最適化の試みです。

これにより節約される時間は、開発者が必要なデータを調べて、変更後にコードが適切に機能するかどうかを確認するための余分な労力によって無駄になります。

テキストの代わりに数字を使用するのは組み込みの本能だと思います。

Mapでのラベルの検索に加えて、余分な文字列の作成にもつながります。スタックで発生しますが、それでもコストがかかります。

すべては個々の選択に依存し、日付まではインデックスのみを使用しました:-)

他のポスターで指摘されているように、そうしない理由が本当にない限り、列名に固執します。パフォーマンスへの影響は、たとえばクエリの最適化と比較して無視できます。この場合、メンテナンスは小さな最適化よりもはるかに重要です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top