バッチ処理はSQLの一括処理で行おう!
バッチ処理はSQLの一括処理で行うべきです。
しかし、バッチ処理を一括処理で行うときには一括でできる処理量の限界は存在し、それはマシンのスペックによって違います。限界を知っていれば怖くはありません。これまでも何度か、開発ではなく、テストや保守でも、SQLができるかどうかで大幅に工数が違うと書いてきましたが、それも合わせて、限界をみていきましょう。
条件はテストサーバがあって、本番と同じデータが入っているとしましょう。対象となるメインのデータの入っているテーブルをTableAとし、対象の処理は日次バッチだとします。
負荷テストの手順は以下の通りです。
- 現時点のピークを特定する
- ピーク時点のリソースの消費量を測り限界を予測する
- テストデータを作る
- 予想した限界量のデータでテストする
■ 1.現時点のピークを特定する
まずは、本番と同じデータですから最も多くのトランザクションが起きている日を特定します。
SELECT 日付 -- , 区分など
, COUNT(*) CNT
FROM TableA
GROUP BY 日付 -- , 区分など
ORDER BY COUNT(*) DESC
※ サブクエリーにしてROWNUM(Oracle)、TOP(SQLServer)、
LIMIT(PostgreSQL)などで1件だけ取り出す。
これは、日付にインデックスがあった場合、そのインデックスをフルアクセスする処理時間なので、そんなに時間は掛かりません。
注意する点は、RDBMSのバージョンによってはCOUNT(日付)にしないとインデックススキャンにはならない点ですが、最近は、ほぼ COUNT(*)で問題ないようです。日付にインデックスがなかった場合は TableA をフルスキャン&ソートする処理時間とほぼ一致します。もちろん、日次バッチという処理があるのに、日付にインデックスがないという構造は大問題ですが……。
普段からSQLを書いていれば、このようなSQLは一瞬で出てきますから、実際のプログラムでは使用しなくても、SQLを知っていることでテストや保守でも非常に楽ができます。
■ 2.ピーク時点のリソースの消費量を測る
上のSQLで特定した日付でバッチ処理を実行したときのメモリ(今はハードディスクが問題になることは稀なので)使用量の増加を測ります。
実メモリの空き ÷ 処理中に使用したメモリ = 限界倍率
という式で限界倍率を予想します(ものすごく乱暴ですけどね……)。今回は10倍付近に限界があるであろうと仮定し、現状の10倍のデータを作るとします。
もし、この時点で、メモリ不足が起きているなら処理の分割を検討します(後述)。
■ 3.テストデータを作る
テストデータは普段一括処理している人は、SQLで10倍のデータを作ることも簡単に出来ます。
ちなみに、これは一気に作らずに9回実行したほうがいいけれど……。当たり前の話ですが、問題なく実行できたら10倍のバッチも大体ハードウェアの限界内に納まるでしょう。
INSERT INTO TableA
(カラム羅列)
SELECT
キー の使われていない一文字を置き換える
キー + (a.NUM × (10 ^ キーの最大値の桁数))
, キー以外のカラムの羅列
FROM TableA
, (SELECT 1 AS NUM, 'A' AS KEY FROM DUAL
UNION ALL SELECT 2 AS NUM, 'B' AS KEY FROM DUAL
UNION ALL SELECT 3 AS NUM, 'C' AS KEY FROM DUAL
UNION ALL SELECT 4 AS NUM, 'D' AS KEY FROM DUAL
UNION ALL SELECT 5 AS NUM, 'E' AS KEY FROM DUAL
UNION ALL SELECT 6 AS NUM, 'F' AS KEY FROM DUAL
UNION ALL SELECT 7 AS NUM, 'G' AS KEY FROM DUAL
UNION ALL SELECT 8 AS NUM, 'H' AS KEY FROM DUAL
UNION ALL SELECT 9 AS NUM, 'I' AS KEY FROM DUAL) a
WHERE
TableA.日付 = #先ほど特定した日付#
これで、現時点で一番データ量が多い日の10倍のデータを作ることができます。普段から(……以下略)
■ 4.予想した限界量のデータでテストする
ハードウェアの許容量を超えたときどのような動作になるか確認します。
基本的にハードディスクがパンクしない限り、スワップを起こして遅くなるぐらいで済むはずです。
一括で処理するというのは以下のような処理を想定しています。
/* ロック */
/* エラーチェック */
INSERT INTO エラーログ
…
SELECT
…
WHERE
エラーの条件;
/* ログの出力 */
INSERT INTO ログ
…
VALUES(……);
/* データの出力(または更新) */
INSERT INTO 出力先
…
SELECT
…
WHERE
…
AND NOT EXISTS
(SELECT * FROM エラーログ
WHERE エラーログ.キー = メイン.キー);
/* ログの出力 */
INSERT INTO ログ
…
VALUES(……);
/* ロック解除 */
COMMIT;
※ ログは自律トランザクションでCOMMITする
一括で処理すると、COMMITまでの処理がサーバのワークエリア(メモリや一時エリアなど)で行われることになりますので、領域が足りなくなると、最悪、止まってしまうことがあり得ます。
しかし、現状のハードウェアの状況を見ると、一般家庭のPCでさえ普通に2GByteものメモリが載っています。月次処理で1月分の生データを処理する必要があったとしても、パンクすることは少なくなっています。
確かにループで処理するとハードディスクの容量一杯までパンクは起きません。事実上、「パンクしません」と言い切ってよいし、逆に、一括処理をしてリソース不足で止まってしまうことはありました。わたしも昔パンクさせた経験があるけれど、その頃ってサーバで256MByteでも積んでる方だった。わたしにとっては、今のメモリとかハードディスクの容量というのは天文学的に感じるのですが……。
単純に上のテストデータを作った処理をループと一括処理の両方でを書いてみれば分かりますが、パフォーマンスは5~20倍違います(もちろん、クライアントやAPサーバからループすると、もっとパフォーマンスに差が出ます)。コーディング量は約2倍になるでしょう。
たとえば、一括処理で現状のピークで10分掛かるバッチ処理があったとしたら、ループすれば10倍掛かるとすると1時間40分掛かります。今回、その10倍の負荷テストを行ったわけですが、一括処理なら1時間40分、ループすれば16時間40分も掛かります。事実上破綻していますね。
現状であれば、パンクの可能性よりもパフォーマンスにこだわった方が良いシステムができるのです。
もちろん、工数についてもさらに問題があって、テスト時間10倍、テストデータを作るのも10倍の差が出ます。コーディング量が倍というのは開発工数は単純に倍では足りません。テスト工数を開発工数に含めると、バッチ処理についてはトータルで2~5倍前後の差になり、納品物のパフォーマンスも何度も書いている通り大変な差になります。
とはいえ、バッチ処理の場合、ループすることにメリットがないとは言いません。処理を細分化している分、システム全体に一時的に掛かる負荷は減らせますし、処理の進捗率も分かります。しかし、そのためにトレードオフする工数やパフォーマンスも、あまりに惜しいでしょう。
現状のハードウェアでは、ループして処理するメリットは極僅かしかありません。
もし、現状でもパンクする、あるいはパンクに近い状態であるならば、種類の少ない(区分、種別、営業所、工場等々の種類だけループ)で区切って処理をすれば良いでしょう。
処理が速く工数も掛からないので、浮いた工数で十分な負荷テストをして、分割する単位を検討すればよいわけです。
繰り返し(区分、種別、営業所、工場等々でループ)
/* ロック */
/* エラーチェック */
INSERT INTO エラーログ
…
SELECT
…
WHERE
区分など = 条件
AND エラーの条件;
/* ログの出力 */
INSERT INTO ログ
…
VALUES(……);
/* データの出力(または更新) */
INSERT INTO 出力先
…
SELECT
…
WHERE
…
区分など = 条件
AND NOT EXISTS
(SELECT * FROM エラーログ
WHERE エラーログ.キー = メイン.キー);
/* ログの出力 */
INSERT INTO ログ
…
VALUES(……);
/* ロック解除 */
COMMIT;
繰り返し終了
「一括で処理するなどできるわけがない!」そうでしょうか? 確かに、要件によってはできないかもしれません。
その判断はどこにあるか? スキルがなければ限界を測ることも、できないかどうかも判断できません。
わたしは一般的に頑固者といわれます。しかし、わたしは両方を検討してよい方を選んでいます。一方で、わたしを頑固者だと思う人は、片方しか検討していないことがほとんどです。それで「できるわけがない!」と最初から決め打ちしています。そう思う人がプロジェクトにいたら、確かにできないです。
パフォーマンスが、10倍も20倍も違えば夜間バッチをオンラインバッチに変更して、業務のグランドデザインまで変わる可能性もあるのに……。
夜間バッチをオンラインバッチにするかどうかはコンサルレベルの話で、顧客から話を聞いた瞬間にどこまで予想できるかによって決まっています。ですからこそ、上流技術者がパフォーマンスが予測できる程度の技術力を持つべきなのです。でも、上流技術者ほど持ってないですよ。
「できるわけがない!」と決めうちしているうちは、いつまで経っても進歩はないのです。ループで決めうちしてくる頭の固い頑固な人はイヤだな~。会話が成り立たない。
わたしのところに相談が回ってくるのは、散々工数を使い果たした後なんで、ちっとも儲からない。失敗する前に話したことは無視されて、失敗が確定してから相談されても……、唯々、悲しみと空しさを溜めるだけでどうにもならない。
どうにかならないかな……。
コメント
AC/DC
前のとこに書こうと思ったら新しいのがアップされているのでこっちに。
ずっと読んでますが、なんか子供っぽいね。生島さんもハツカさんも。
ハツカさんはIT業界の方じゃないようなので、
技術的な部分で的はずれになるのは仕方ないけど、もうちょっとIT業界のことを勉強した方がいいと思うよ。
ここは初心者向けじゃないんで、flatlineさんの言うとおり会議室の方がいいんじゃないかな。
たぶん技術的なことがあまり理解できない分、過激な言動にばかり反応しちゃって、
売り言葉に買い言葉ってなってるっぽい。
これじゃ子供のケンカだよ。
生島さんの言ってることは技術的には共感できる部分も参考にできる部分もあまりないから、
コラム自体をそれほど深く読んでたわけじゃないけど、ちょっと読んだだけでも論理的におかしい部分がいくつもあるのは確かだよね。
ていうか自分の持ってきたい方向に強引に理論をねじまげてって方が正しいかな?
なんか自分がSQLできるのを自慢してるようにしか読めないんだよね。
テストデータまでSQLで作るって???だよ。
まあ、この人の場合は過激な言動も含めてそういうことを計算づくでやってるんだろうけどね。
だからちょっと突っ込まれると話をそらすか、出てけって怒鳴るか、
必殺コメント非表示攻撃に走る。
あ、「営業妨害するなメール」を送るってのもあるんだっけ。
自分が間違ってないと思いこんでるから、ていうか、自分が間違える可能性を考えてないから、
そういう可能性を示唆されるだけで過剰反応するんだよね。
「おれの言うこと理解できない?それはお前の頭脳が足りないからだよ。だっておれは間違ってないもん」
ってのは子供の証拠だよ。
自分の主張したいことが読み取ってもらえない → 読み取れない方に問題がある
これはいい年した大人の考え方じゃないでしょ。
普通は自分の言ったことを見直すよね。
エンドユーザに「バグでましたけど」っていわれたとき、
「それは仕様です。バグだと思えるのはあなたに仕様を読み取る能力がないからです」
って言うわけじゃないでしょ。
もうちょっと謙虚になろうよ。
これまで自分の主張として書けるコメントにしか反論してないしね。
ちなみにハツカさんコメントはまあどうでもいいとしても、
> プログラムを作るというのは、業務をプログラミング言語に翻訳するという
> 仕事で、SQLなんてって人は、「単文の羅列でも意味は通じる」という主張で
> しかないのですけれどね。
こりゃどう考えても変でしょ。比喩が。
flatlineさんの言葉を借りるなら「SQLではなく別の言語で翻訳するというだけ」ってことだよね。
それから学歴も資格もない人が、「学歴なんて」「資格なんて」って言わない方がいいよ。
学歴コンプレックス、資格コンプレックスにしか聞こえないからさ。
生島さんがSQLすごい自慢はいいからさ、そろそろ別の話題にしてくんないかな。
AC/DCさん、こんばんは。
> こりゃどう考えても変でしょ。比喩が。
> flatlineさんの言葉を借りるなら「SQLではなく別の言語で翻訳するというだけ」ってことだよね。
Aという言語と、Bという言語で翻訳するとします。
議論するには、どちらかの言語ができない人を対象にすると、できない人は逆の言語では無限大に時間もパフォーマンスも悪くなるから比較はできません。
ですから、Aという言語の達人と、Bという言語の達人と、それぞれが翻訳したとしてどちらが効率的か比較しないと意味がないです。議論するならそれぞれ十分なベテラン同士で、コーディング量や、最適化した記述でのパフォーマンス = 理論値で比較するしかないですよね。
つまり、理論値で、どちらが工数、パフォーマンスが良いかです。
中途半端なレベルの技術者にフォーカスして比較しても理論としては意味がない訳です。
理論値で、SQLより工数、パフォーマンスともに上がる方法があるなら、その言語でやるべきです。
私は可能な限り、理論値に近い、具体例を挙げています。
しかし、この記事だけでなく、いろんな例を挙げていますが、私より、工数が下がって、パフォーマンスを出す例は出てきたことがない。
私も間違ってないか不安ですから論理的な意見は大歓迎です。
(「炎上しても」と書いてきましたが、もちろん、炎上して欲しいとは書いていませんけど)
私と同じ具体例を、もっと効率的な違う言語で示して欲しいわけですが、そういう意見はなく、できない人の言い訳は聞いても仕方がないので、イライラしています。
> テストデータまでSQLで作るって???だよ。
???なんですか?、私には残念ながら意味が分かりません。
テストデータを作るプログラムなど、できるだけ短く簡単であるべきです。
もっと簡単な方法(サブクエリーはテスト用にビューにしてることもありますが……)提示してみましょうよ。
それが正しい反論で、私も待ってますよ。
???では何の説得力も何もないですな。(私が馬鹿なのか……)
ちなみに、まさかとは思うけれど、SI Object Browserなどは、内部的に同様のSQLで処理しているのも多いですから、「ツールで作れば」は勘弁して下さいね。
具体的にこの記事でも、他の記事でもコーディング量もパフォーマンスも下がるモノを出せるなら、私はすぐに納得します。
工数(開発・テスト・保守)は、どんなにコピペしても、コーディング量のn乗に比例します。別の言語でツールから自動で出力できるなら、SQLも同じように自動で出力できますから変わりません。理論的に
工数 = コーディング量のn乗 × 言語自体の難易度
ただし、nと難易度からコーディング量が2倍以下の差なら、工数は僅かに逆転することがありますが。
現実論としてできない人が多い。
それは認めていますし、それを認めれば多くの意見は正しいです。
あとは、どのレベルまで『できない』を認めるかですが、できないのレベルが高校生ができる(以下略)
ヤス
コラムを読みながら「こういう使い方もアリか」と考えさせられました。
いろいろと汎用度が高い技術を教えていただいてありがとうございます。
今度テストデータを作る際に利用させていただきます。
今まではクロスジョインアップデートを繰り返してきましたが、断然こっちのほうが制御が簡単そうですね。
しかし、相変わらず変な人たち多いですね。
別の言語に翻訳じゃなくて、RDBMSの母国語を考えろよと思ったり。
次のコラムもSQLを使う人間にとって有益なコラムを期待しております。
でも、使わない人におっても有益さがわからないと、上級にたどり着かないからなぁ……
とにかく次も期待しているのでがんばってください。
ヤスさん、おはようございます。
現実のプログラムでは、いろんな大人の事情で使えなくても、テストでは使えるのです。
このコラムでもテクニックだけを書いているわけではないですから散乱はしていますが、テクニックの部分を適当に読んで応用して頂ければ幸いです。
テストや保守でSQLで処理するクセを付ければ、半年もすれば勝手にできるようになっています。
今できないことは別に責めないけれど、「できなくても良い」という人は、使わないので永久に伸びないし、できる人の邪魔しかしない。
工数5倍、パフォーマンス10~20倍って、右折のできないタクシードライバみたいなモノですわ。直進と左折だけで目的地に行けることもあるし、右折しないといけない場所でも、遠回りして10~20倍の時間を掛けても良いなら、直進と左折だけでも大抵の目的地には着けるでしょう。
目的地に着けるからプロなんですかね?
oumi
今回のような記事は良いですね。
抽象度が低い分受け入れやすいし、貴社のセミナー他への訴求力も増す気がしました。
こういった、より抽象度の低い内容から、「何故上流・超上流でSQLの知識が必要なのか」を論じて行く方が、安心して見ていられると思いました。
「できるわけがない!」と決めうちしている人には、より現実で説くか、政治で説くかしかなかったりしますし…
(あ~心象ってのも大事な属性か…^^;)
y
自分ではバッチ処理なんて一括でやることが当たり前だと思っていました。
が、頭の古い人ほど頭が堅くて衝突することが多々ありました。
(元COBOLerがその傾向になり易いらしい・・)
説明を何度しても一括でやることを想像できないらしいです。
自分では理解できないから切り捨てる。
嫌な考え方です。
AC/DCさん
> テストデータまでSQLで作るって???だよ。
生島さんが言及しているのはパフォーマンスに関する件ですので
パフォーマンステストというフェーズでの話しではないでしょうか?
数値検証やら詳細(数値や条件による分岐)を確認する部分を
手作業で作成したデータを使用するのは言語道断でしょうけど。
AC/DC
ほらほら、また自分の主張に沿うようにねじまげてるよ。
それとも、本当に自分で気付いてないのかなあ。
> プログラムを作るというのは、業務をプログラミング言語に翻訳するという
> 仕事で、SQLなんてって人は、「単文の羅列でも意味は通じる」という主張で
> しかないのですけれどね。
> Aという言語と、Bという言語で翻訳するとします。
> 議論するには、どちらかの言語ができない人を対象にすると、
> できない人は逆の言語では無限大に時間もパフォーマンスも悪くなるから比較はできません。
翻訳するってことの意味が違っちゃってるね。
> テストデータを作るプログラムなど、できるだけ短く簡単であるべきです。
なんで?誰が決めたの?
どうも生島さんのコラムって「~べき」が多いよね。
簡単なプログラムでできるものなんて簡単なデータでしかないでしょ。
そんな単純なテストデータだけでテストしてるってことかい?
複雑な業務ならテストデータも複雑になるじゃん。
あたりまえのことだけど、量的なテストはもちろんのこと大切だけど、質的なテストの方がずっと大切だよね。
そういうまともな技術者なら考えることを、わざとなのかうっかりなのかしらないけど
まるで無視してるもんだから、???って書いたわけ。
世の中ってそんなに単純じゃないんだよ。
自分が顧客だとしても元請けSIerだとしても、そんな単純なテスト計画出されたら、一発でやりなおしって言うよ。
> . 夜間バッチをオンラインバッチにするかどうかはコンサルレベルの話で、
> 顧客から話を聞いた瞬間にどこまで予想できるかによって決まっています。
あはは、本気で言ってる?
顧客から話を聞いた瞬間に予測できたとするよね。
でも、その予測が正しいって根拠はどこにあるわけ?
話聞いたコンサルなりSEなりの経験と勘?
経験者なら間違えないってのはなしね。予想は予想にすぎないんだからさ。
ま、仮に1万歩ぐらい譲って完璧に近い予測ができたとするよね。
最初の要件定義、ってか、それ以前の段階で聞いた話に基づいて立てた予想で、
ずっと開発走らせるっての?途中で要件変わることとか考慮しないの?
まさか今どきウォーターフォール?要件定義書に検印もらったら「ここに書いてある
こと以外はやらないよ」ってやつ?
最初の、正しいかどうかわからないような予測なんて何の役に立つの?
前後するけど、
> 私は可能な限り、理論値に近い、具体例を挙げています。
これも同じね。
生島さんがあげてるような具体例ってさ、具体的じゃないんだよ。
理論は理論にすぎないからさ。
つまり実業務に応用できないってことね。
理論だけで仕事が回るほど世の中は単純じゃないってこと。
> しかし、この記事だけでなく、いろんな例を挙げていますが、私より、工数が下がって、
> パフォーマンスを出す例は出てきたことがない。
そりゃあ生島さんがそういう例を選んで書いてるからでしょ。
それにここにコメントで書けるような単純な例なんて、やっぱり実業務に応用できないよね。
あとさ、
> でも、上流技術者ほど持ってないですよ。
これも誰が決めたの?統計でも取ったわけ?
生島さんの短い経験の中でいったい何人の上流技術者に会ったの?
自分の狭い世界の体験や経験を、さぞ一般論みたいに語るのはやめようよ。
> 工数5倍、パフォーマンス10~20倍って、右折のできないタクシードライバみたいなモノですわ。
だからさ、比喩が変なんだってば。
タクシードライバーってことは二種免許必要だよね。
右折できなかったら技能試験通らないよ。
右折できないタクシードライバーなんて存在しないわけ。少なくとも日本はね。
SEとかPGみたく免許いらない職業と、医者やタクシードライバーみたいに免許制の職業を
比較すること自体が変じゃね?
1つ前になるけどさ、
> わざとなのでしょうけれど、はてしないほど読解力なさ過ぎです。
> 二度と来ないで下さい。
このサイトって生島さんが運営してるの?
違うよね?
お金出してスペース借りてるの?
違うよね?
「二度と来ないで下さい」って、何様のつもり?
素直に「商売のジャマだから、私の意見に賛成できる人以外はコメント書くな」って本音で書いたら?
これもコメント非表示攻撃されちゃうかなあ。
ヤス
負荷テストで複雑な内容のデータは必要ないし、
負荷をかける為のデータを作るために、一時間で一万件のデータを作るプログラムと、一分で一万件のデータを作るプログラムがあるとします。負荷テストをやるのにどっちを使いますか? 普通に考えればわかりますよね?
コンサルの提案は間違っていたら訂正しに行けばいいし、重要なのは検討できること。選択肢に出せない人はその方法をとることは出来ません。重要なのは選択肢の中で最適解を選ぶことでは?
右折しか出来ないタクシーに乗りたい人なんですか?
俺は絶対に嫌ですな。時間も金も掛かる。
右折で最短ならそれでいいし、左折を混ぜた方が最短ならそちらがいい。
プロフェクトに選ぶ方針もそれと同じ。時間と金どちらに銃身をおくかは案件しだいではありますけどね。要は選択肢があることが重要である。という話。
皆さん、こんばんは。
議論にならない人のコメントは消させて頂きます。
が、消してもしつこく書いて来られる本物のストーカがいるので少し。
>> 工数5倍、パフォーマンス10~20倍って、右折のできないタクシードライバ
>> みたいなモノですわ。
>
> だからさ、比喩が変なんだってば。
> タクシードライバーってことは二種免許必要だよね。
> 右折できなかったら技能試験通らないよ。
そうですよね。
右折ぐらい(ド素人の)教習生でもできることですね。
SQLぐらい(ド素人の)高校生でもできることです。
右折を避けたら、目的地に着くのに10倍も20倍も掛かることもあるでしょう。
SQLを避けたら、結果が出るのに10倍も20倍も掛かることも相当ある(場合によっては100%ある)のです。
タクシードライバにとっておかしいことなら、IT技術者にとってもおかしいことでしょう。
医者にしても(少なくとも看護師を素人とは思ってないけど)、タクシードライバにしても、あり得ないけれど、IT技術者に置き換えてSQLができないというのは、『同じぐらいあってはならないこと』という比喩ですね。
それで、なおかつ、現職のプロ(を名乗っている人)が「だからどうした」と、公に言うのはかなりマズいですわな……。
どうも、極めて簡単な比喩(嫌み)が理解できないほど、日本語が苦手な方のようですが、本文とご自身のコメントを100回ぐらい読んでみて下さいな。
ちなみに、消す権利はオーナにありますので、主張がしたかったら他所でやって下さい。あまりにレベルの低いコメントは、次、書いても消すよ。
もっとまともな意見にコメントすべきなのですけどね……。
宝春
こんばんは。
AC/DC様
たまには、感情的なコメントというのも見てて微笑ましいのですが
もうちょっと簡潔にまとめるか、ひねりを加えていただかないと
読んでても面白くないです。次は、面白いのを期待してます。
本文には特にコメントすることがありません。ごめんなさい。
次回を楽しみにしてます。
追伸
でも、ケンカは面と向かってやったほうが断然面白いと思います。
flatline
こんばんは。
なんか来るなとか言われたけど、名前違ってたし、消したければ消すでしょ。
> 負荷テストで複雑な内容のデータは必要ないし、
そうですか?
私なら負荷テストでこそ、複雑な内容のクエリーたくさん投げたいですけどね。
テーブル7つぐらい結合してるとか。
まあ、AC/DCさんは、ちょっと読み違えてるなとは思いますけどね。
またはわざとやってるのかも?
唯一、
> 最初の、正しいかどうかわからないような予測なんて何の役に立つの?
ってのは同意です。
仕様変更/追加があたりまえのプロジェクトばかりやってきたせいかも
しれませんが、初期段階のパフォーマンス予測とか見積なんて、だいたい
開発後半になると役に立たなくなってる、というのが経験値としてあるので。
宝春
flatline様
> 私なら負荷テストでこそ、複雑な内容のクエリーたくさん投げたいですけどね。
> テーブル7つぐらい結合してるとか。
失礼ながら、おっしゃっている意味がさっぱりわかりませんでした。
負荷テストで複雑なクエリーを投げたい?????
何の負荷テストなんだろう?
#私が読み違えてるかも、自信なくなってきた・・・。
ところで、テーブル7つ結合って複雑ですかね?
flatline
宝春さん、こんばんは。
> 失礼ながら、おっしゃっている意味がさっぱりわかりませんでした。
> 負荷テストで複雑なクエリーを投げたい?????
> 何の負荷テストなんだろう?
んーと、そうですね、適当な例が浮かばないですが、
たとえば、
select * from hoge where hogeId = ?
に対するcost が、1.0 だとして、
select * from hoge left join hoge2 on hoge.hogeId = hoge2.hogeId2
left join hoge3 on hoge2.hogeKey = hoge3.hogeKey
where hoge.code in (?,?,?)
and hoge2.name like 'aaaa%'
and hoge3.no between 100 and 200
order by hoge.seqno
に対するコストはいくつかを調べたいとかですかね。
7つ結合が複雑かどうかはまあ一例です。
1つのテーブルに対するより複雑でしょということで、深い意味はないです。
こんばんは。
以前から思っていた感想ですが、物事の例えを突っつくのではなく、”その例えを用いて書き手が何を言いたいのか”を考えてみては如何でしょうか。
私は『自分にとってプラスになる情報の収集』を目的にして、開いた時間にエンジニアライフを閲覧していますので、挙げ足取りには興味がなく、書き手の意図が解るまで何度か読み返しますよ。(書き手が悪いなどと言う厚かましい反論をする感性はありません)
本題から脱線した議論(?)の連続で焦点を置き去りにした挙句、コメントが100近くになってしまう。そして後から見る人が『なんじゃコレ』となってしまうのが勿体なく思います。
忙しいのに……、イライラするので。
> select * from hoge where hogeId = ?
>
> に対するcost が、1.0 だとして、
>
> select * from hoge left join hoge2 on hoge.hogeId = hoge2.hogeId2
> left join hoge3 on hoge2.hogeKey = hoge3.hogeKey
> where hoge.code in (?,?,?) → IDの間違いですな。
> and hoge2.name like 'aaaa%'
> and hoge3.no between 100 and 200
>
1.0と全く違う処理をしているので意味ないでしょう。
比較対象は
select * from hoge where hogeId in (?,?,?)
order by hoge.seqno;
結果をループして
select * from hoge2 where hogeId2 = ? and hoge2.name like 'aaaa%'
select * from hoge3 where hogeKey = ? and hoge3.no between 100 and 200
ですわな。
処理量はほぼ同じで、ループした分オーバーヘッドのコストが増えているだけだから、処理件数にもよるけれど大体20~30倍の差になる。テーブルが7個もあれば30倍ではきかんし、and hoge2.name like 'aaaa%' や and hoge3.no between 100 and 200 をSQLで処理せず、APサーバやクライアントで読み飛ばしたら更にコストが掛かる。
JOINする対象にインデックスがなくても、DBサーバでやれば大抵ハッシュジョインになるけれど、外から回せばネスティッドループにしかならんしね。hoge2、hoge3をキャッシュしているならまた別ですが。
こんなモノは、意味が分かっていたらテストする意味はない。
外側でループした方がコストが掛からないなら、ちゃんとSQLが書けてないだけ。
このレベルでは、初期の段階で立てたパフォーマンスの予測は役に立たんだろうね……。
ちなみに、LEFT JOIN効いてないバグだし……。
正しくはこう(馬鹿らし、メッチャサービス)
select *
from
hoge
left join hoge2
on hoge.hogeId = hoge2.hogeId2
and hoge2.name like 'aaaa%'
left join hoge3
on hoge2.hogeKey = hoge3.hogeKey
and hoge3.no between 100 and 200
where hoge.code in (?,?,?) → IDの間違いですな。
あ~り~
総合的にみて面白いコラムです。。。大爆笑です。
消えているコメントがとても気になりますが・・・
えっと・・・
>条件はテストサーバがあって、本番と同じデータが入っているとしましょう。
>対象となるメインのデータの入っているテーブルをTableAとし、
>対象の処理は日次バッチだとします
って条件ありきのコラムですよね?
でもっての負荷テストですよね?
>「ツールで作れば」は勘弁して下さいね
>そんな単純なテストデータだけでテストしてるってことかい?
>複雑な業務ならテストデータも複雑になるじゃん
>負荷テストで複雑な内容のデータは必要ないし
とまぁ色々とぶった切りで引用しましたが・・・このコメント全部意味不明。
実データ使ってるんです。実データを倍増させているんです。
複雑も簡単もないですよ。
実データ使ってるんです。実際に発生した状況を再現しているんです。
最初のコメが分かりませんが、ツールで・・・っていう反論をさせるコメントが
あること自体・・・「???」です。(これも引用w)
複雑な業務なら・・・って業務のデータ利用だって言ってるじゃん。
想定したデータじゃないんですよ。
たしかに、とある一日で全パターンでるとは思いませんが、それってただ単純に
日付をある1日ではなく1ヶ月とかExpによってはとあるデータは3年分とか使えば良い訳で。。。
と、普段と違う感じでコメントしてみました。
コメント内で発生した議論は・・・コメントする立場になさそうですね。
が、1点だけ。
・・・翻訳の意味は同じっぽいのですが・・・。
P.S. できればコメントは残しておいていただきたい。
一方的感が強くなるので。。。それがどんなに的外れでも、どんなに前提条件を満たしていないコメントでも。。。
saki1208
生島さん、こんばんは。
なんか今回も盛り上がってるなw
すでに存在するデータのn倍化なら、rownum + 階層問い合わせ なんかでも
簡単に作成出来ますね。
# 日付範囲の展開や存在しないデータを無理やり作りたい場合にも適用でき
# ます。多用するととんでもない目に遭ったりしますが...
大量データを必要とするテストではシステム上の入力で出来たデータや旧シ
ステムから移行したデータを元にしてよくやってます。
本番データをテストに使用できないケースも最近は増えていますし。
# もちろん、個々の仕様については色々な想定の元に作成したデータでテス
# トを行った前提での話になりますけどね。
saki1208
連投すみません。
前提条件が漏れていました。
Oracleでの話です。
皆さん、おはようございます。
本文に詳しく文法解説を書いてないからいけないのでしょうけれど、実データを10倍にする方法を書いています。
多分、SQLを知らない、普段使わない人は、「変なことしている」だけで読み飛ばして終わっているのかな。更に言い掛かりを付けたりして訳分かりませんが、まぁ、そういう人もいるといるということですよね。
本文にあるものも、基本的には初級シスアドをそんなに超えてないというか、範囲内だと思います。それでも「そんなことできるわけがない」と頭ごなしに否定して終わり、という人は現場では多いですから、そういう人が絡んできてもおかしくないですね。
テストや保守では使っても実際のプログラムには入らないSQLを書いてみましたが、初級シスアドレベルなら本文を読んで理解できるはず。普段から使っていたら、パフォーマンスやループで書いたときの工数の差を体感的に理解していますし、マシンと実データの量から限界がどの辺にあるかも理解しているはずです。
そうすると、実際の開発で「なぜ使わないのか?」と疑問を持つことになると思うし、開発で使えない原因がどこにあるかというと、「設計段階で想像も付かない人が設計しているから」ということも分かってきます。
コーディングから、テスト、保守でも必要で、設計にも大きな影響を与えるのですから、全技術者に必須の技術と言えるのです。テスト、保守では実利がありますから、実際のプロジェクトでやってみたら「右折せぇよ!」っていう私の怒りが分かると思いますが……。
テストや保守で使うぐらいの応用力があるかどうかは、技術者の大きな分かれ目でしょうね。
応用力があるというのは、つまり使いこなせている。
読んでも分からないというのは、初級シスアドレベルを超えてない。
試せばすぐに分かることですから、試しもしないで絡んで来るなんて技術者としてどうかと思う。
それでも、多分、ここでコメントする人の大半は普通よりはできる人で、現場での技術者の分布は、確実に頭ごなしに否定する人の方が多い。結果は「右折できないタクシードライバ」よりも大きな差が出そうですけどね……。よく考えたら、右折しなくても10倍の差はなかなかつかないわ。
結局、できない人をどこまで許すかで、お客様が「右折できないタクシー」に乗っていることに気づかないとどうしようもないのですね。
ちなみに、単文の羅列とは。
select * from hoge where hogeId in (?,?,?)
order by hoge.seqno;
結果をループして
select * from hoge2 where hogeId2 = ? and hoge2.name like 'aaaa%'
select * from hoge3 where hogeKey = ? and hoge3.no between 100 and 200
と
select *
from
hoge
left join hoge2
on hoge.hogeId = hoge2.hogeId2
and hoge2.name like 'aaaa%'
left join hoge3
on hoge2.hogeKey = hoge3.hogeKey
and hoge3.no between 100 and 200
where hoge.hogeId in (?,?,?)
のちがいです。
RDBMSを使うのに外側の言語で処理しようとしたら、必ず単文の羅列になります。
oumi
多分に要望に近い物ですが・・・
個別のアプリケーション(例えば1つのクラス)などが、効率の良いSQLを出そうが出すまいが、上流工程ではまったく興味が無いはず。
なぜなら、「当然、それなりの(または最適な)パフォーマンスであるべき」という暗黙(または明確)の条件があるのが通常でしょう。また、当然そのように構成・設計されているという前提(意識)があるはずです。
ですので、シスアド級の知識云々は技術者しかも、比較的プログラミング寄りの話と捉えられる事の方が、より多いと思います。
(実際の試験の内容の話ではありませんので、たぶんに私見といってよいです。)
上流工程(技術者)や超上流工程(技術者)へ訴求する話題であれば、1SQLの話では無い物、そういったテーマがおのずとあるはずです。
そういった事に対する記事を経験を通して書かれると良いのではないでしょうか。
きっと面白いと思います。
実際、上流以前で、システムの設計を評価(検討)する場合、個別のアプリケーションから発行されるSQLそのものが、どうであるかは評価しません。できないですし。
論理的にまたはモデル的に、RDBMSのオブジェクト使用数の多少や使用方法は評価対象になります。
当然、モデルケースにおいて、どのようなSQL文が発行されるかという想定での検討などはあります。(初期のパフォーマンス計画などではこういったモデルで検討しますね。)
少々細かい話をすると、テーブルの関係性やインデックスの数量(場合によってはDIKS配置やブロックサイズなどの物理面についても)などは評価の対象になります。
というような事もありますから、「1SQLに閉じた何か」ではない事について、体験からの記事を書かれる方が、より上流工程に対して訴求力があるであろうし、面白いと思います。
そのうえで、シスアド級知識や高度なSQLの知識がどのように絡んでくるのか、が面白いはず。
仮にもう少し開発が進み、1つのアプリケーションについての上流(設計)である場合でも、その仕様調整の場で「どのようなSQLが発行されるか」は、特に意識される事は無いと思います。(何かの瑕疵でチェックする体制になったとかは無しw)
なぜなら、その仕様説明や調整の場で、「10分で終わるコードが書けます」「持ちかえらせてください。」別にどちらでも良いのです。結果が良ければ良いのです。(心象はおいておいて)
この場合、事前のニーズとして(または潜在ニーズ)あるのは、「(将来的にも)整合性や性能を保てるか」「システム全体への影響度」「未知の問題点やその可能性」などについての話題です。
いずれもシスアド級知識などではどうしようもないものだと思います。
こういった事について、RDBMSとの関連を、体験からの記事を書かれる方が面白いと思います。
逆に、「そうではないケース」があるのかもしれません。そのようなケースにぶち当たった事がないので、それはそれで興味あるところです。
また、
例えば、「こうだとします」ではなく、「実はこんなことがありました」のほうが、面白いと思います。
この「例えば、こうだとします」がかなりアレですから・・・
といった事を過去記事を振り返って思いだしながら、つらつらと書いてみました。
どうも、上流牛術者への訴えかけに弱いのではないかと思いましたので。
書く本人じゃないから、言えるっていう面もあるかもしれません(^^;
naruhodo
>資格に関しては、「資格は持っているが実際に仕事をやらせたらほとんど役に立たない」とか、「資格は何の役にも立たないし、そんなものにはまったく興味がない」「技術は、実際に仕事で経験して身に付けるもの」といったことがよくいわれる。こうした昔の職人かたぎのようなことをいっているエンジニアに限って、新しい技術を取り入れようとせず、柔軟な思考を持っていない、といったことがある。実際に筆者の周囲にもそうしたエンジニアがたくさん存在する。彼らに共通して見られる特徴は、向上心がなく、物事を決め付けて判断するような傾向があるのではないだろうか。あるいは、自分の経験で築いてきた知識を試されるのが怖いのかもしれない。
これってあなたにぴったり当てはまると思ったのですが違いますか?
Twitterでの論争を見て思っただけですので、違っていたらすいません。
naruhodoさん、おはようございます。
日本語が苦手なようですが……。
資格の勉強は系統立てた知識を得るために必要。
資格を取る以上は範囲の知識を実力として持ちなさい。
ところが、資格があっても実力になってない人が多い。
それは合格を目指すから。合格ではなく実力を付ける方を目指しなさい。
採用する側で資格のあるなしで採用を決める会社は、派遣中心の会社です。
若い有資格者は年々増えるので簡単に陳腐化して、置き換えられる。
そういう会社に駒として採用されたいなら止めない。
って言ってるのです。