sql >> データベース >  >> RDS >> Mysql

MySQLJDBCDriverのcachePrepStmtsとuseServerPrepStmtsの違いは何ですか

    まず、クライアントとサーバーのプリペアドステートメントを区別することが重要です。

    クライアントが準備したステートメント

    クライアントのプリペアドステートメントは、「エミュレートされた」プリペアドステートメントです。これは、SQLステートメント文字列がクライアント側でトークン化され、実行のためにステートメントをサーバーに送信する前に、プレースホルダーがリテラル値に置き換えられることを意味します。完全なSQLステートメントは、実行のたびにサーバーに送信されます。一般ログを使用して、これがどのように機能するかを調べることができます。例:

    次のコード:

    ps=conn.prepareStatement("select ?")
    ps.setInt(1, 42)
    ps.executeQuery()
    ps.setInt(1, 43)
    ps.executeQuery()
    

    ログに表示されます:

    255 Query  select 42
    255 Query  select 43
    

    「クエリ」は、プロトコルレベルで、COM_QUERY コマンドは、次のステートメント文字列とともに送信されます。

    サーバープリペアドステートメント

    サーバーのプリペアドステートメントは「真の」プリペアドステートメントです。つまり、クエリテキストがサーバーに送信され、解析され、プレースホルダーと結果の情報がクライアントに返されます。これは、useServerPrepStmts=trueを設定したときに得られるものです。 。ステートメント文字列は、COM_STMT_PREPAREを使用してサーバーに1回だけ送信されます。 電話(文書化されたここ )。各実行は、COM_STMT_EXECUTEを送信することによって実行されます プリペアドステートメントハンドルと、プレースホルダーの代わりに使用するリテラル値を使用します。

    クライアントが準備した例とは対照的に、同様のコードブロックを使用できます(ただし、今回はサーバーが準備したステートメントを有効にします):

    ps2=conn2.prepareStatement("select ?")
    ps2.setInt(1, 42)
    ps2.executeQuery()
    ps2.setInt(1, 43)
    ps2.executeQuery()
    

    そして、ログには次のように表示されます:

    254 Prepare    select ?
    254 Execute    select 42
    254 Execute    select 43
    

    ステートメントが実行される前に準備されていることがわかります。ログは私たちに好意を示し、実行の完全なステートメントを示していますが、実際には、実行ごとにプレースホルダー値のみがクライアントからサーバーに送信されます。

    プリペアドステートメントのキャッシュ

    多くの接続プールは、接続の使用全体でプリペアドステートメントをキャッシュします。つまり、conn.prepareStatement("select ?")を呼び出すと 、同じPreparedStatementを返します 同じステートメント文字列を使用した連続呼び出しのインスタンス。これは、トランザクション間で接続がプールに返されるときに、サーバー上で同じ文字列を繰り返し準備することを回避するのに役立ちます。

    MySQLJDBCオプションcachePrepStmts この方法で準備されたステートメント(クライアントとサーバーの両方で準備されたステートメント)をキャッシュし、ステートメントの「準備可能性」をキャッシュします。 MySQLには、サーバー側で準備できないステートメントがいくつかあります。ドライバーは、サーバー上でステートメントの準備が可能であると判断した場合はその準備を試み、準備が失敗した場合は、クライアントが準備したステートメントにフォールバックします。このチェックは、サーバーへのラウンドトリップが必要なため、コストがかかります。このオプションは、このチェックの結果もキャッシュします。

    これがお役に立てば幸いです。




    1. 複数の行に値を分割する

    2. Oracleにはフィルタリングされたインデックスの概念がありますか?

    3. pysparkを使用してPostgreSQLに接続する

    4. MySQLまたはMariaDBデータベースに接続する方法