2016-07-21 2 views
1

準備文でバインド変数を使用しない場合、パフォーマンスは低下します。 1以下バインド変数を持たないPreparedStatementはパフォーマンスに影響しますか?

String selectSQL = "SELECT USER_ID, USERNAME FROM DBUSER WHERE USER_ID = '101'"; 
PreparedStatement preparedStatement =  dbConnection.prepareStatement(selectSQL); 

私が知っている好ましい。

は、以下の例を考えてみましょう。 それは彼らが、ハードも、彼らはプリペアドステートメントを使用している文字列リテラルをコード化されているすべてのクエリでの私のプロジェクトの1ので尋ね、この質問SQLインジェクション

String selectSQL = "SELECT USER_ID, USERNAME FROM DBUSER WHERE USER_ID = ?"; 

を防ぐことができます。

+1

両方のクエリはSQLインジェクションから安全です。最初のものが動的変数としてuseridを取得しない限り。 – Abhishek

+1

@Abhishek例はおそらく残念です。私は彼が '' SELECT ... WHERE USER_ID = '"+ userId +"' "のような何かを意味すると思います。 – Thomas

+0

@Thomas彼はそれだけを意味すると思います:P – Abhishek

答えて

1

準備されたステートメントは、ステートメントを準備することを意味します。つまり、これをデータベースに送信し、データベースがすでにその文を解析/コンパイルできるようにします。これは、頻繁に実行される文に便利です。

パラメータ化された文は、多くの場合、準備された文に関連するため、頻繁に実行されます(値を送信するだけで、サーバはクエリを実行する準備ができています)。

しかし、頻繁に実行される「静的な」ステートメントであっても、ステートメントの準備(特に「複雑なステートメント」の場合)のメリットがあります。使用される別の手法は、ストアドプロシージャ内でクエリを実装することです。このようにして、クエリはすでにコンパイルされており、サーバーは実行時にストアドプロシージャコールをコンパイルするだけで済みます。

救急処置を準備していない(接続を閉じるなどの)場合にのみ機能します。したがって、プリペアドステートメント要求でプリペアドステートメント要求でサーバーをオーバーフローさせないように、プールとプリペアドステートメントキャッシュが必要な場合があります(プリペアドステートメントはサーバー側のリソースを必要とします)

SQLインジェクションから保護するために、文字列ではなくデータ型)。しかし、これは準備されたステートメントの利点に直面しています。 (両方のクエリがSQLインジェクションに公開されていないことに注意してください)

2

パラメータを使用するかどうかは、主にユースケースによって異なります。ステートメントの準備と実行に費やされた時間を監視すると、ステートメントの準備が実際の実行よりも非常に高価になることがわかります。したがって、準備を保存できるかどうかによって異なります。

あなたは常にこのようなシナリオで勝つ:

PreparedStatement stmt = dbConnection.prepareStatement(...); 
stmt.setInt(1, x); 
stmt.executeQuery(); 
... 
stmt.setInt(1, y); 
stmt.executeQuery(); 
... 

あなたは準備倍に保存しているため。これはDBMSに依存しません。

一部のDBMSでは、サーバー側のキャッシュがあります。彼らが何をどのようにして行うのかは、ベンダーやバージョン固有のものでさえあります。ここでは、サーバが両方の文が本質的であることを識別することができる

PreparedStatement stmt = dbConnection.prepareStatement(...); 
stmt.setInt(1, x); 
stmt.executeQuery(); 
... 
PreparedStatement stmt2 = dbConnection.prepareStatement(...); 
stmt2.setInt(1, y); 
stmt2.executeQuery(); 
... 

:しかし、我々は、Oracle DBMSに時々このようなシナリオではかなりスピードアップを得るのですか、より頻繁に使用されている文をparametrisedことを学びました2番目の声明に対する同じ準備時間と準備時間が大幅に削減されました。これは固定ストリング・ステートメントでは機能しません。サーバーが判別できないため、同じです。

私は考えていませんが、パラメータ化されたステートメントを使用すると固定ストリングステートメントよりも遅く測定できるシナリオがありますが、その逆もあります。

関連する問題