アカウント名:
パスワード:
オンライン・トランザクション処理でミリ秒単位のレスポンスを要求するシステムではPreparedStatementの使用が事実上必須ですね.
Oracleの場合, SQLのコンパイルにかかる時間は(もちろんSQLの記述によって全く異なりますが)おおよそ数100msのオーダー, 一方コンパイル済みのSQLをキャッシュから探すのが数msのオーダーです. そのため秒間数10~数100程度の問い合わせがあるシステムでは, 動的SQLを使うとデータが十分にバッファリングされてIO負荷に問題の無い場合でもCPUネックでシステムが回らなくなる場合があります. 一般には多くの業務システムでSQLキャッシュヒット率は95%以上が望ましいと言われていますが, 経験的には大規模システムで確実に回す場合, 最低でも98%. 99%以上もあたりまえって感じです.
あと, ある程度以上の規模のシステムではRDBMSサーバとアプリケーションサーバが分離されていてネットワークで繋がっているという構成も多いです. この場合RDBMSサーバ側でできるだけ条件判断を行わせてRDBMSサーバとアプリケーションサーバ間のネットワークに余分なデータを流さないというのも性能に効いてきたりします.
しかし,webアプリの検索フォームなどでは,プリペアドステートメントは使えない場合が多かった.検索条件項目が複数存在していて,いずれの項目も必須で無い場合,項目が入力されているかどうかをチェックし,それに合わせてSQL 文の WHERE 句の内容をツギハギしなければならないからだ. SQL文そのものも,そしてそれにセットする引数の個数も可変なので,プリペアドステートメントを使うのは無理だったのである. 今回思いついたのは,このような条件で,プリペアドステートメントを使う方法である.
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
Stay hungry, Stay foolish. -- Steven Paul Jobs
とりあえず (スコア:0)
原理的にSQLインジェクションは発生しないので。
でも結局のところは一生懸命情報を収集するしかないのですけれどね。
Re:とりあえず (スコア:0)
その分だけのPreparedStatement作るんですか?
Re:とりあえず (スコア:1)
情報源は定かではないのですがJavaの場合、PreparedStatementを生成する際に
コンパイルされたSQL文はキャッシュされるはずですので
Statementを都度生成するより効率的です。
誰か詳しい人、補足をお願いします…;
Re:とりあえず (スコア:1)
結果を使いまわすキャッシュがあったはずです。
あらかじめPrepareしておけばこのキャッシュから探す手間も
省けます。
が...
条件によってSQLを動的に生成するという事は、下手するとキャッシュ
にヒットしないんじゃない?
私だったら、デカイSQLでRDBMS側に条件判断させる事も検討します。
そうしないと、SQL動的生成する部分に脆弱性っつかバグが紛れ込む可能性
が出てきますから。
# 実行計画次第ですがね。
wild wild computing
Re:とりあえず (スコア:3, 参考になる)
オンライン・トランザクション処理でミリ秒単位のレスポンスを要求するシステムではPreparedStatementの使用が事実上必須ですね.
Oracleの場合, SQLのコンパイルにかかる時間は(もちろんSQLの記述によって全く異なりますが)おおよそ数100msのオーダー, 一方コンパイル済みのSQLをキャッシュから探すのが数msのオーダーです. そのため秒間数10~数100程度の問い合わせがあるシステムでは, 動的SQLを使うとデータが十分にバッファリングされてIO負荷に問題の無い場合でもCPUネックでシステムが回らなくなる場合があります. 一般には多くの業務システムでSQLキャッシュヒット率は95%以上が望ましいと言われていますが, 経験的には大規模システムで確実に回す場合, 最低でも98%. 99%以上もあたりまえって感じです.
あと, ある程度以上の規模のシステムではRDBMSサーバとアプリケーションサーバが分離されていてネットワークで繋がっているという構成も多いです. この場合RDBMSサーバ側でできるだけ条件判断を行わせてRDBMSサーバとアプリケーションサーバ間のネットワークに余分なデータを流さないというのも性能に効いてきたりします.
Re:とりあえず (スコア:1, 興味深い)
実際以前よりは動的SQLにパフォーマンスに難が無くなりました。
Prepare構文に変換出来るものは内部的に変換してキャッシュ率上げるとか。。うろ覚え。違ってたらごめんなさい。
それでも最初からPrepare使った方が早いですし、インジェクション対策にもなるので良いのは変わりませんが。
Re:とりあえず (スコア:1, 興味深い)
そのコンパイル時間によってOSとDBサーバアプリのI/O WAITも
隠蔽され、性能分析/改善が難しくなります。
まず最初に動的SQL潰しをやってから真面目に分析しましょう、
なんて話はよくありますし、その分改善コストがかさみます。
単発ツールなら別ですが、システム開発であればPreparedは必須で、
動的SQLの使用は許可制が良いかと。
# オフトピックですいません。
Re:とりあえず (スコア:0)
ここに出てこないのは、皆あまり使わないのかな?PHPのサンプル [doyouphp.jp]
Re:とりあえず (スコア:1, 興味深い)
NULLとUNKNOWNを積極的に活用するSQLの書き方 [no-ip.info]
Re:とりあえず (スコア:0)
その際に外部から引き渡された値を使わなければいいだけ。
外部から引き渡された値はプレースホルダを使ってDBに渡す。
# しかしSQLインジェクションってクラサバの頃からある話だと思うんだけどなぁ。
# 何でWebアプリだけ問題にされるのか不思議。
Re:とりあえず (スコア:1)
># 何でWebアプリだけ問題にされるのか不思議。
間接的にでもインターネットにつながってる事が必須のDBだからじゃないでしょうか。