罪と罰(11) 変革への序章
五十嵐さんがイニシアティブを設立した背景を知ったことが原因だったのか、Aチームメンバーの意識は目に見えて変わっていった。元々、五十嵐さんの登場によって変化の兆しはあったものの、それがさらに加速された形だ。
1つの例としては、3バカトリオが繰り広げていたネバーエンディングな議論が、皆無にはならなかったものの激減したことだ。おそらく、プロジェクトAを何としても成功に導かなければならない、という五十嵐さんの強い思いが伝わったこともあったのだろうが、単純にやるタスクが増えて、議論に費やしている時間がなくなったことも大きいだろう。やる気の出る目標を与えると、若手エンジニアのモチベーションは劇的にアップするものだ。
以前なら、1日に1回は、デザインパターンがどうの、リファクタリングがどうのと議論するのが3バカトリオの日課だったのに、今では、プロジェクトAの仕様について真剣にブレインストーミングなどをやっている。おかげで、私の負担とストレスはかなり軽くなっていた。
しかし、最もドラスティックな変化を見せたのはマサルだった。これまでは、言われた仕事は黙々とこなしていたものの、積極的に意見を述べるような傾向は皆無だったのだが、先日の大学訪問から帰った翌日、不意に私のデスクまで歩いてくると口を開いた。
「あの、ちょっと考えてみたんですが」
「な、何を?」驚きながら私は訊き返した。熱でもあるのか、とかバカなことを言わなかったのは我ながら上出来だ。
「blazeDsで、FlashとJavaでデータをやり取りするとき、DTOを使いますよね」
「うん、そうね」
「ActionScriptの方と、Javaの方と両方コーディングしないといけないじゃないですか」マサルは熱心な顔で言った。「それを自動変換してソースを吐き出すようなツールを作ってはどうでしょう?」
「......ああ、なるほど」
確かに、これまでDTOでデータをやり取りするときは、Javaで作成したDTOのプロパティをコピーして、ActionScriptのDTOに貼り付けてから、
public String hoge; → public var hoge:String;
といった具合に書き直していた。難しいことではないが、こういう作業工数も積み重なるとバカにできないし、何より面倒だ。自動化できるのであれば、それに越したことはない。
当然、世の中には同じことを考える人がいるので、Eclipseのプラグインとして使える変換ツールもあり、私も試してみたことがある。だが生成されるActionScriptファイルの記述が、私の好みに合わなかった――プロパティ名がアンダーバーで始まっているとか、不要なgetter/setterが生成されたりとか――ことと、JavaからActionScriptは生成できても、その逆ができなかったので、使うのをやめてしまった。
「そうね」私はいくつかのパターンを思い浮かべた。「Stringとか、int とか、そういう単純な型は対応表を作っておけばできるね。配列は全部Arrayでいいか。別のDTOをプロパティにしてるのはどうする?」
「そういうのは、とりあえずObjectにしてしまえば」
「まあ、それしかないね。でも何で作る?JavaScriptでとか?」
「Airで作ったらどうでしょう?」
「Air?」一瞬、意味がわからなかったが、すぐにマサルの言いたいことがわかった。「ああ、Airのデスクトップアプリケーションとして作るってことか」
マサルは大きくうなずいた。
きっとプロジェクトAに貢献できる何かがしたいのだろう。確かにAirのコーディングができる人間がもう1人いてくれると助かる。
ふと気がつくと、オフィスルームに居合わせた全員の視線が、マサルの背中に集中していた。マサルはそれに気付くこともなく、ただ、私の返事を待っていた。
「わかった。やってみ」
「はい!」
入社してから発した音声中、最大デシベルの返事を残してマサルが戻っていくと、隣のカスミさんが心の底から感心したような顔で囁いた。
「いやあ感動したわ。あのマサルがあんなに積極的になるなんて。お母さん、嬉しい」
クミも負けてはいなかった。これまでPHP以外の言語にはほとんど見向きもしなかったのに、通勤時間と休み時間を利用してJavaの解説書などを勉強しているようだった。少しでもプロジェクトAに貢献できるように自分を変えていこうと決めたのだろう。
ある日の昼食時に、クミがカロリーメイトをかじりながら、デザインパターンの本を熟読しているところに、武田さんがキングジムファイルを抱えてやってきた。
「藤崎さん、これ、急ぎでコピー頼む。午後イチで顧客に持って行かなきゃならないんだ」
いつもなら「えー面倒だなあ」とか言いながらも引き受けていたクミだが、このときは反応が違った。
「今、休憩中なんです」
素っ気ない様子に武田さんはやや鼻白んだものの、それでもこれまで通り最後にはやってくれるだろうと思ったのか、なだめるような口調で続けた。
「まあそう言わずに頼むよ。顧客への提出物だからさ」
するとクミは、食べかけのカロリーメイトを飲み込み、ペットボトルのお茶を一口飲んでから、武田さんの顔を正面から見た。
「どうしてご自分でやらないんですか?」
「は?」武田さんは呆気に取られた顔になった。「いや、俺はこれから昼を食いに行くから......」
「あたしは今、お昼を食べながら勉強してるんです。外に食べに行く時間がもったいないから自分の席でです。そのコピーはそれを中断してまで、あたしがやらなければいけないんですか?武田さんが他にたくさん仕事を抱えていて、手が離せないというのなら別ですけど、ランチに行くんですよね、これから?自分のランチタイムは削れないけど、他人のランチタイムなら削ってもいいってことですか?」
私は思わず息を呑んで2人を見守った。ドア付近で武田さんを待っていた久保さんと村瀬さんも、驚いたように凝固している。私の記憶にある限り、クミが武田さんにここまで言ったことはない。
武田さんの顔が朱に染まった。その口から怒鳴り声が飛び出してくるかと思ったが、かろうじて自制心がブレーキをかけたようだ。
「わかった」低い声で武田さんは答えた。「もういい」
武田さんは踵を返すと複合機の方へ歩いていき、それを見送ったクミは、平然とした顔で食事と勉強を再開した。
これ以後、年長組の人たちがクミに雑用を命じる回数は大幅に減ったのだった。AチームにはWebシステム開発部の命運を左右するプロジェクトを進めている、という自負と大義名分があり、逆に年長組には自分たちがお荷物になるのでは、という懸念が常にある。これまでの職位を元にした命令体系ではなく、実績と実力による発言権が生まれようとしていることを、誰も口には出さないものの確実に感じてはいた。武田さんが引き下がったのも、それを誰よりも実感していたからなのだろう。五十嵐さんが、そこまで計算して荒木准教授の話を聞かせたのだとしたら、脱帽と言うしかない。
私はAir for Mobileアプリケーションのひな形作成を続けていた。最初の頃は、内蔵カメラのコントロールに数日を費やしたりしていたが、だんだんモバイル特有の制限などが身についてくると、何となくコントロールやスキンの挙動が予測できるようになってきた。そうなると、あれこれコンポーネントを組み合わせて、新しいコンポーネントを作るようなことが楽しくなってくる。HTMLではどうしても冗長な記述になってしまう画面も、Airだとクロスブラウザ対応など気にせずに作成できるので、ついつい熱中してしまう。
こういう時間が取れるのも、他のメンバーが率先して、要件のまとめやテーブル設計などを進めてくれるからだ。
五十嵐さんは、仕様や実装にはあまり口を出そうとせず、毎日のように都内、県内の大学を訪問していた。たまにメンバーの1人か2人を一緒に連れて行くこともある。今のところ、色よい返事をもらってはいないが、興味を示してくれた大学もいくつかあるそうだ。
「とにかく動くものが欲しいな、早めに」五十嵐さんは翌週のミーティングの席で私たちに言った。「1画面か2画面ぐらいでいいんだ。それがあるとないとじゃ、やっぱり全然違うからな、先方の印象が。別にちゃんとサーバに接続したりしなくても、紙芝居で充分なんだが、iPad上で動いていることが見せられればな」
「またプレッシャーが......」私は呻いた。「何とかやってみます。近日中にということで」
「よろしく頼むよ。さて、テーブル設計の方はどうだ?」
「今のところこんな感じです」少し自信なさそうな顔で、守屋がER図を広げた。「まだ途中なんですが」
「ふーむ」一瞥して五十嵐さんが唸った。「箕輪さん、どう思う?」
「そうですね......」私はER図を見た。「とりあえず主キーは複合キーにしないで、それぞれのIDを作った方がいいですね」
「そうだな。他には?」
「今のところはそれぐらいです。まあ悪くはないと思いますが」
「悪くない」五十嵐さんは頷いた。「悪くはないが、良くもないなあ」
「どっちですか」守屋が訊いた。
「きちんと正規化されていると思うんですが」木下が言った。
「うん。正規化はされてるんだけどな。じゃ、たとえばだな、美和学園大学の他に、別の大学が使いたいと言ってきたとするわな。その大学では、企業の情報として最寄り駅を使いたいとする。その場合、どうする?」
「最寄り駅フィールドを追加します」足立が答えたが、すぐに不安そうな顔になった。「っていうのは、きっと正しくないですね」
「正しくないわけじゃない。それでも用は足りるからな。でも、また別の大学が、企業の公式Twitterアカウントを項目として欲しいと言ってきたら?ノー残業デーの有無を欲しがったら?その都度、追加していくか?」
3人は沈黙した。五十嵐さんは私に視線を移した。
「どうだ、リーダー、何かアドバイスをしてやっては」
「そうですね......」私はもう一度ER図を睨んだ。「項目を追加できるようなメンテナンス画面を作っておくとかですかね......」
「うん、それも1つの手だな......」五十嵐さんはうなずいて、語を継ごうとしたが、別のメンバーの声がそれを遮った。
「あ、あの!」
発言したのはマサルだった。私たちが驚いて見つめる中、五十嵐さんだけは眉ひとつ動かさなかった。
「うん。聞かせてもらおうか」
「企業データ項目を列として持つんじゃなく、行として持ったらどうでしょうか」
「うん?」守屋が首を傾げた。「どういう意味だ?」
「えーと、つまり、まず項目を定義するテ、テーブルを作って......」
マサルはつっかえながら説明し始めたが、木下が手を上げた。
「ちょっと待て」木下は予備のER図を出すと、4色カラーボールペンと一緒に渡した。「ほら、そこに書けよ」
マサルは顔を輝かせて礼を言うと、ER図を書き始めた。ゆっくりと丁寧に長方形を描き、フィールド名をきれいな字で書き加えていく。私たちは息を殺すように、その作業を見守っていた。
10分ほど黙々と書き進めた後、マサルはようやく顔を上げた。
「あー、なるほどね」足立が素直に感心した。「この発想はなかったなあ」
「うん。グッジョブ!」五十嵐さんも手放しで褒めた。「いいね、これは。お見事だ。もうちょっと精査する必要はあるが、この考え方はいいな」
私もマサルを賞賛しつつも、悔しい思いを味わっていた。なんで、こういうやり方を思いつかなかったのか。
「くそ、悔しいな」守屋が私の心の中を読んだみたいに言った。「考えもしなかった」
「それはだな」五十嵐さんが真面目な顔になった。「君たちの先輩たちからの負の遺産だよ。最初に君たちが書いたように、列をひたすら増やしていくのは、COBOLの時代からの名残だ。不幸にもそういう教育を受けてしまったんだな。予備カラムを設けろ、とか言われなかったか?」
「あー、言われました。確かに」
私にも覚えがある。以前、久保さんの業務を手伝ったとき、あらゆるテーブルに、
filler1 varchar2(100)
filler2 varchar2(100)
filler3 varchar2(100)
とか入っているのを見て不思議に思ったものだ。久保さんに存在理由を訊いたら、当然のような顔で「何かあったときの予備だよ」と言われて呆気に取られたことがある。
「あ、でも、これだと結合が多くなりませんかね」木下がER図を指で辿った。「これとこれとこれをJOINしないと、1つの値が得られませんよね」
「それも負の遺産だなあ。逆に訊くけど、なんでJOINが増えるとまずいと思うんだ?」
「え、そりゃあ、パフォーマンスが低下するからでしょう」
「ブブー」五十嵐さんは妙な異音を発して、手を顔の前でクロスさせて×の字を作った。「それは間違い」
「え?」
「きちんと適切に正規化されていて、適切なインデックスが張ってあれば、JOINによるパフォーマンス低下なんか、誤差の範囲でしかない。むしろ、だらだらと列を増やしていく方が遅くなる」
にわかには信じがたい、という顔をしている3バカトリオだった。
私がRDBのノウハウを学んだのは前の会社でだったから、今、五十嵐さんが言ったようなことは理解していたし、それを変えるような理由もなかった。だが、Aチームの他のメンバーは、これまでRDBについて、あまり深い部分まで学ぶ機会がなかった。そのため、この会社に入ってから、武田さんや久保さんによる教育を受けたことで、先輩方のやり方をそのまま受け継いでしまったのだろう。かくいう私も、あまり自慢できたものではない。いつの間にか、そのやり方に疑問を抱かなくなっていたのだから。
マサルもこの会社に入ってからRDBの教育を受けたのだが、実業務ではデザインを担当することが多かったので、ほとんど身についていなかったに違いない。それが幸いして、このように自由な発想が生まれたのだろう。
とにかく、この一件以来、3バカトリオがマサルを見る目は、確実に変化した。これまでは、Photoshopを使うのは得意だが、システム開発という分野においては大したスキルを持っていない後輩、としか見ていなかったのが、いきなり設計に関するセンスの良さを見せつけられたのだから。
私から見ても、いい緊張感が生まれつつあった。このチームはきっとうまくいく、と思ったのは、このときだ。
このまま何事もなく開発が進んでいれば、プロジェクトAは予定よりずっと早く完成し、多くの関係者に幸福をもたらしたに違いないが、ハッピーエンドで終わる事例の方が少ないのが、この業界の不条理なところだ。私たちの目の前に立ちふさがる障壁が明らかになったのは、年度が変わった最初の週だった。
(続く)
この物語はフィクションです。実在する団体名、個人とは一切関係ありません。また、特定の技術・製品の優位性などを主張するものではありません。
コメント
BEL
よく出来たドラマのような雰囲気になってきた。
最後の段落からもそんな気がするが、
こういうときはきまって、いい意味でどんでん返しかましてくれるのが、
今までのリーベルGさんだったと思う。
私はActionScriptとかその辺は疎いので、
この人達がやろうとしてることが全うなのかはわからない。
c#er的には"とりあえずobject"とか危険な香りなのだが。
データ構造の話してると思ったから、
「項目を追加できるようなメンテナンス画面を」って
答えになってないと思ったけど普通に会話すすんでた。
ntm
今回も引き込まれる内容でしたね!
最後の段落を見て、あぁやっぱりそうくるか…と思い毎週月曜日が待ち遠しいです。
夏芽
>当然、世の中には同じことを考える人がいるので、Eclipseのプラグインとして使える変換ツールもあり、私も試してみたことがある。だが生成されるActionScriptファイルの記述が、私の好みに合わなかった――プロパティ名がアンダーバーで始まっているとか、不要なgetter/setterが生成されたりとか――ことと、JavaからAcrionScriptは生成できても、その逆ができなかったので、使うのをやめてしまった。
下の方が「AcrionScript」とスペルミスしていますよ。
p
うーんいい雰囲気だからこれから落とし穴があるんだろうな、と思うあたりだいぶ調教されている気がする
しかし武田さん…
ダイイングメッセージ2
>BELさん
ActionScriptですが、フラッシュで使われているスクリプト言語で、
昔調べた際の印象ですとかなりちゃんとした魅力的なOOLです。
(wikiをみると私が調べたのはver2の様です)
10年近く前に調べた内容ですので詳細は忘れてしまいましたが、
VBの様なインチキクラスではなく継承可能なちゃんとしたクラス、名前空間によるクラス群の分離、ちゃんとした型付け、、、、と存外にしっかりした言語で、私が調査した限り、当時としてはJavaアプレットと共にただ二つの「まともな」動的Webアプリを組む事か可能な手法であり、Javaのイベントハンドラ周りに対する致命的な思想欠陥(=OO原理主義で効率と柔軟性が最悪)を考えるとクライアントサイドで安定してしっかりした動的Webアプリを組むための唯一無二と言ってよい環境でした。
ですので、イベントハンドラ、GUI部品周りの処理がC#やJavaよりもちょっと便利な普通のOOLと思っていて読んでいれば大丈夫だと思います。
Objectクラスに関しては、このケースは全然問題ないかと。
全て基底であるObjectクラスを只の汎用クラスとして使う場合に恐れるべきは型のミスマッチ、特にCのポインタの様な型情報のロストやVBのObject型の様な型化けですが、作中のお話のケースですと、型のミスマッチはテストの初期段階で確実に検出できる(できなければならない)ことですので。
Objectクラスにアレルギーがあるのでしたら、基底としてMyDTOFieldクラスを定義すればよい話かと思います。
匿名
これから武田さんによる執拗な妨害工作が始まる・・・?
さすがにそんな分かりやすい悪役はいないか
初心者
fillerを入れないのは当然として、結合増やしても問題ないとは知らなかったです。性能を求めて正規化くずすっていうのは負の遺産だったのか・・・
確かにパッケージで拡張性が必要なところとかはこういう設計してますよね。
a
生徒と呼ぶのは小学校から高等学校までで、大学からは学生と呼ぶのではないでしょうか?
小学校の生徒、
中学の生徒、
高校の生徒、
大学の学生、だったと思います。(違っていたらすみません)
aさん、どうも。
気になって調べてみたところ、
「中等教育機関」で学ぶ人 → 生徒
「高等教育機関」で学ぶ人 → 学生
と呼ぶのですね。
じゃあ、この二つの違いは、というと、
「生徒」→「既知の事実を学ぶ人」
「学生」→「未知の予測を実証する人」
だそうです。
なので、確かに「学生」が正しいですね。
でも、イメージファイルを修正するのも面倒なので、
この図を作った3バカトリオの誰かが、うっかりしていた、ということにしましょう。
BEL
>aさん
本題ではないですが学校教育法的には小学生は「児童」でしょうね。
>ダイイングメッセージ2さん
ActionScriptは、Flashで使うaddEventListenerとかするアレ、程度には知っています。
勉強会的に触ったこともあって、おおむねおっしゃるような印象でした。
Objectクラス自体にそれほどアレルギーがあるわけではなく
どちらかというと「"とりあえず"Object」という発想がひっかかった感じです。
C#で.NET Frameworkの中のクラスにもobjectが返ってくるようなものはありますし。
JavaがOO原理主義に感じるのは言語自体によるものもあると思いますが、
Javaとともに浸透していったプログラム技法や風習によるものが大きいと思ってました。
>初心者さん
「性能を求めて」という明確な理由があって「正規化くずす」って
ちゃんと認識してるなら、負の遺産とは言い切れないと思います。
「(インデックスはればJOINしても)"問題ない"」といっても
例に出てるようなマスタなら確かに問題ないですが、
レコード数や更新頻度によるわけで(それこそ何百万レコードに秒単位でUPDATEとか)。
特に「列を増やしていく方が遅くなる」ケースがあまり思い浮かびません。
ba
処理速度が遅くなるかどうかは知りませんが、開発速度は間違いなく遅くなるでしょうね。
そして、まともな正規化が出来ない人は、まともなカラム名を付けられるわけもなく。kingaku_1 , kingaku_2 , ... とか、「おいおい勘弁してくれよ...」なカラムを100個くらい平気で定義してくる(汗
oldtype
武田さん、若い頃に雑用やらされてたのかな。それを今の若いのにやってこの結果だと変わり目の人ってことでちょっとかわいそうな気もしなくはない。
ただ最初にクミは見た目で雑用を頼まれるって話だったけども。
実績と実力による発言権はいいけど、職位とか上司を別にした完全に無視する
のはどうなんだろうかと思う。やっぱり混乱するよね。
だったら実績と実力の職位にするのがいいんだろうけど、すぐにそういうわけ
にもいかないか。
あと、新しいものがすべて悪しきものではないとは思うし。
DumbObj
列じゃなくて行として持つというのはよく分かるんですが、マサルさんのER図はよくわからなかったです。
特に、企業募集データと募集詳細データの関係が。
話の流れとして、最寄り駅やTwitterアカウントは企業に依存するデータという前提だと受け取ったんですが
そういった"企業"に依存するデータの項目を、"募集項目マスタ"で管理し、
各企業の最寄り駅やTwitterアカウントを、"企業募集データ"で管理するということなんでしょうか?
でも、それだと、テーブル名がおかしいですし、企業募集データと募集詳細データ詳細の関係もおかしいです。
それとも、守屋さんのER図で、企業・年度・募集職種に依存していた業務内容や初任給といったデータ項目を、
"募集項目マスタ"で管理するということなのでしょうか?
そのほうが、テーブル名としてはしっくり来ますが、
その場合も、募集職種や年度の項目が無いので関連がよく見えません。。。
理解できた方がいましたら、解説いただけると助かります。
Q
このシステムは学校間では就職関係データの共有をしないってことなんでしょうか。そうすると自分の学校だけで集められる情報って実はけっこうたかが知れてたりしませんか?特に荒木先生のいる女子大なんか学生は少ないし、歴史は浅いし。
いわゆる就活サイトとの差別化をどうはかるんでしょう?
そう思う反面で、個人情報を扱うわけなので他の学校と同じユーザのテーブルに入れるのもなんとなく不安はあります。
アルゴ
DumpObjさん
最寄り駅なんかは、企業情報というよりは、採用情報なんじゃないでしょうか。Twitterアカも採用専用のがあるので。
dotJ
こんな感じ?
五十嵐さんが言っているように、もう少し精査は必要かもしれませんね。
■募集項目マスタ
募集項目ID : 3, 募集項目名 : "年度", 項目種類 : 数値
募集項目ID : 4, 募集項目名 : "募集職種", 項目種類 : 文字列
■企業情報マスタ
企業ID : 150, 企業名 : ○○株式会社
■企業募集データ
企業募集データID : 211, 企業ID : 150, 募集項目ID : 3
企業募集データID : 212, 企業ID : 150, 募集項目ID : 4
■募集詳細データ
募集詳細ID : 422, 企業募集データID : 211, データ(数値) : 2013
募集詳細ID : 423, 企業募集データID : 212, データ(文字列) : "一般職、技術職"
DumbObj
>アルゴさん、
どうもありがとうございます。Twitterアカウントは採用専用のがあるんですね、知らなかったです。
そうすると、企業情報じゃなく、他の項目と同じで、採用情報の一項目として設計しようとしていると理解したほうがよさそうですね。
>dotJさん、
どうもありがとうございます。すごくわかりやすいです。
年度も募集職種もデータとしては、募集詳細データで管理するイメージなんですね。。
そうすると、企業募集データと、募集詳細データを分けているのは、企業ごとに項目が変わってもいいようにしているということですね。なるほど。
ただ、この場合、2013年のA社のSE職といった採用情報のまとまりが、一つのエンティティとして表現されないのが気になってしまいます。。
でも、全体的にマサルさんの意図したイメージがわかったきがするので、助かりました。
どうもありがとうございます。
mayo
リーベルGさんはFlex業務で使ったことあるのかな?
それだったら仲間なのでうれしいなっと
使ったことある人ここにいるのかな?
とある初心者
カラム増やすと遅くなるって、行連鎖とかそういう問題でしょうか。
この程度の単純なマスタならともかく、大量のトランザクションデータを
扱う場合にJOINよりカラム追加の方が問題になるってそんなに多いケースかなぁ。
それともあくまでこの程度の単純なマスタが前提のお話?
正規化理論すらまともに抑えてない人らは論外だとしても、
正規化-JOINよりも非正規TBLの方が効率が良い面なんて多々あるのに、
この五十嵐さんの論調はどうも・・・
朱雀
非正規化テーブルの方が速いという誤解はありますね。
結合=遅い、という固定観念がまかり通っている気がします。
正規化と非正規化の応答速度実証実験
http://www.doaplus.com/html/bun/bun03_20051101.html
JOINでパフォーマンスが下がるという幻想
http://bleis-tift.hatenablog.com/entry/20080705/1215230798
Q
>とある初心者 さん
確かにこんなのその時々でいろいろだから五十嵐さんの決めつけたしゃべり方は
ちょっと抵抗がありますよね。
でもそういう決めつけをして強引にすすめていかないと変わらないのかもとは
思います。
アラファイブ
JOINの話ですが、昔ながらの「,」でつなげるJOINは、その表現力の過剰な豊かさのせいで、
HASH JOIN以外では実現できなくなり、鬼の様に遅くなるのでは無いでしょうか?
INNER/LEFT JOINの書き方だと、表現力が制限される代わりに、NESTED LOOPでも実現でき、
納得がいく様になるのでは無いでしょうか?
今のシステムでも前者ではだめではないでしょうか?
へろへろ
>カラム増やすと遅くなる
「AもしくはBもしくはC」という検索をする場合、カラムがすべて違うとカラムごとの検索結果のORになるから、各項目にインデックスがあっても非効率的な検索になってしまう。
(3回、別々のインデックスで検索するか、テーブルを全件取るか)
1カラムにできればIN句で列挙して、一回のインデックススキャンで事足りるわけだし、こういうことじゃないかな?
DumbObj
カラムを増やすと遅くなるというのは、レコード長が大きくなることによるオーバーヘッドを指してるのではないでしょうか?
とある初心者さんが書いてる行連鎖もその一つですが、1ブロックあたりのレコード数が減るので、I/O回数が増えますし、更新があるテーブルであれば断片化も起きやすくなります。
>アラファイブさん、
カンマで書いた場合と、明示的なJOIN構文を使った場合とで、特定のJOIN方式になるという話は、初めて聞きました。知ってる範囲では、OracleやSQL Serverなどではそういう制限はないと思います。
あと、Hash Joinが一概にNested Loopより遅いということはないと思いますよ。Indexなどの状況によりますが、データ量が多い場合などはHash Joinのほうが有利になるケースのほうが多いです。
とある初心者
>>Qさん
たしかに、多少強引でも推し進めないと変革は出来ないというのはありますね。
若い人たちには特に、レガシーな考えを元に教育された「常識」が弊害になる場合は多そうですし。
>>へろへろさん
勉強不足ですみません。
おっしゃってる事は確かにその通りだと思うのですが、非正規(正規系崩し)で
そのような条件の差が発生するパターンがイマイチ思いつかないです。
>>アラファイブ さん
私が主に使用しているDBMSはDB2なのですが、そのような話は初耳でした。
今までNested Loop前提での索引設計、チューニングしかした事がないので
Hash joinについても勉強してみようと思います。
>>DumbObjさん
確かに、I/Oの問題はありますね。
ただ、TBLScanは論外としても、適正に索引設計、SQLチューニングがされている状態でそこまでIOネックになることが今まで無かったのでmピンとこないのが素直なところです。
今まではI/O問題よりもJOINするTBLが増えた場合の結合順番とかのアクセスパスの問題の方が多く発生してたので。
もっと色々勉強してみます。
・・・うちの会社にもこういう話が出来る人が欲しいなぁ。
アラファイブ
「特定のJOIN方式になる」件ですが、Oracleで、
・(+)だと、兄弟JOINの結果を他の兄弟が使えない。
・LEFT JOINだと使える。
というのは、事実だと思います。
そこから、他の兄弟の結果を使えるなら、有る兄弟の実行→別の兄弟の実行と必ずなるのではと(頭の中だけで)思い、あぁそれならNESTED LOOPだ!と思いこんだだけでした。
あと、HASH JOINですが、別の人が泊まり込みで深夜3時までやってもHASH JOINで遅く、プロジェクト全員に招集がかかって、微妙にSQL文をいじって、実機で高い確率でNESTED LOOPになる様にした、なんて事が有り、HASH JOINは遅いんだと思い込んでいました。
HASH JOINの方が有利な事も有る訳ですね。自分は本番のチューニングは部外者ばっかりでしたので、参考になりました。
Q
カラムは増やしても中入れなきゃたいして行長増えないだろって人は
いますし、事実ですが、RDBMSの考えとしてはよろしくないですよね。
Oracleに限って言うと、オプティマイザはHashを選択しやすいと思います。
でも結果の件数が少ない(オンライン処理ではよくあることですので)なら
Nested Loopのほうが有利な場合が多いですから、よくある改善策と
してHashからNested Loopというのが出てくるわけです。
ただ結果の件数がかわるとこれもかわってくるわけで、Oracleのバインド
ピークが邪魔をするなんてこともあります。
今はSPMを活用するのが普通。。。でもないですよね。
>アラファイブさん
SQLをいじるよりヒント突っ込むのが早かったんじゃないかと。
アラファイブ
ヒントはその別の人が(深夜に)やりまくったようでした。
あと、結果の件数とかですが、
1.主テーブル
2.検索するのにとんでもなく重いSFでキーを算出する必要のあるテーブル
3.1レコードのテーブル
とか有って、年締めの一覧を出そうとした際、作ってから数年は良かったですが、
10年以上後になったら、主テーブルに増えまくり、十時間とかかかって、
オンデマンドで欲しい人が出力する事が出来なくなってしまったのですが、
3.を主のテーブルとし、1.をINNER JOINの長兄としてそこで1年に絞り、
2.を次兄として、WHERE句を無くしたら、前と同じように10分程度で出るように
なったりもしました。
本当の「全件」というのも、なかなか無いのでは無いでしょうか?
DumbObj
>とある初心者さん
数件の結果を即座に返すような検索処理だと、例えばレコード長が100バイトから1000バイトになってもそれほどの違いは出ないかもしれませんが、処理する件数が増えると目に見える違いが出てくると思います。もちろん、特定の検索条件のために非正規化し、その結果としてレコード長が大きくなっているような場合は別です。バッチ処理のようにI/Oネックになりやすい処理だと、レコード長による性能差は顕著に出ると思います。
>アラファイブさん
Oracleの(+)で外部結合する場合は、OUTER JOIN構文と違った制限がいろいろとあるんですね。下記にアラファイブさんが書かれたように、利用する構文による結合方式の違いについてコメントしている方がいました。
http://www.oracle.co.jp/forum/message.jspa?messageID=3014662
今のバージョンでも違いがあるのかオンラインのSQL実行環境で少し試してみましたが、違いは出ませんでした。条件がいろいろと違うのでいつも同じだとは言い切れませんが。
http://sqlfiddle.com/#!4/bbf27/1/1
Q
ヒントは適切に与えないとうまくいってるかどうかまったくわからないという状況になる可能性はありますけども。。。そこまでだめといわれると何かバグ踏んでませんでしたか?という話もあります。
SF(StoredFunctionでいいでしょうか?)を使って算出のところはフルスキャンせざるをえないのでしょう。更新への影響はあるものの関数索引を検討してもよかったかもしれません。
(関数索引は厳密な理論でいうと非正規化の一つかもしれません)
もう少し具体的に聞けば策はあるようには思いますが、まあそこまでは。
しかし10年以上もなおさないで使われ続けるというのもすごいですねえ。
ところで結合で「兄弟」というのは一般的なんでしょうか?