社会人であり、技術者であり

2012/11/18 コメント欄の指摘を受け、全面改定しました。

最近、忙しくてすっかりブログを更新していませんでしたが、それでもADPの開発は続けておりその関連で調査をしていましたら、あまりにも程度の低い小説がありましたのでちょっとコメントしてみます。

発端は今から2年前のこの記事になります。

実はオブジェクト指向ってしっくりこないんです!(みながわけんじ)
よく解らない内容の記事なのですが炎上した記事です。ちなみにこの記事のコメント欄のryoというのは私です。


その後、この小説が書かれました。

高慢と偏見(1)隣は何をする人ぞ
高慢と偏見(2)使徒襲来
高慢と偏見(3)コードレビューは踊る
高慢と偏見(4) 嵐の金曜日
高慢と偏見(5) そして戦いがはじまる
高慢と偏見(6) いつかの誰かのためのドキュメント
高慢と偏見(7) 28日後……
高慢と偏見(8) 敵は身内にもあり
高慢と偏見(9) 誰がスケジュール遅らせた? それはあなたとプロマネは言った
高慢と偏見(10) 夏への扉
高慢と偏見(11) 現実は映画じゃない
高慢と偏見(12) 新人くんのささやかな主張
高慢と偏見(13) 一矢
高慢と偏見(終) エピローグ

大変長い小説で、著者(リーベルG)さんはフィクションと言っていますが、この小説は先の記事に対する程度の低い風刺になっています。

こういうのは捨て置いていたらよいのですが、私も齢40を過ぎ、後輩の方達へきちんと伝えるべきことを伝えたほうがよろしいかと思い何が問題か指摘します。

特定の人物を不当に貶める

一番に聞いてみたいことですが、この小説の著者は名誉棄損または誹謗中傷という言葉を知らないのでしょうか?、この著者(リーベルG)さんはいじめ問題がどのような人間の心理から出てくるかわからないのでしょうか?
もっとも今は何を言われても分からないかもしれません。が、まぁ後10年経てば分かるかもしれません。

高慢と偏見の最終話ですが後半は『実はオブジェクト指向ってしっくりこないんです!。』のパロディと思わせるないようとなっています。

後半の出だしを引用します。

アツコさんから久しぶりにメールが届いた。そこには「面白いもの見つけたよ」とあり、1つのURLが載っていた。

 開いてみるとブログだった。タイトルは、

 「SEのサバイバル入門」

 サブタイトルに「過酷なSE業界を生き延びるノウハウを伝授する」とある。ブロガーは「スリービーチ」。スリービーチ? 3つの浜辺? ひょっとして……

 最新の日記は、

 「オブジェクト指向など、実業務では使いものにならない!」


このタイトル「SEのサバイバル入門」とサブタイトル「過酷なSE業界を生き延びるノウハウを伝授する」は当時の、
みながわさんのコラムのタイトルとサブタイトルのパロディであることが分かるでしょう。
今のみながわさんのコラムのタイトルとサブタイトルは違うものになっていますが、当時のみながわさんのコラムのタイトルとサブタイトルは、こちらで確認できます。

その他の類似例を表にまとめます。
高慢と偏見最終話実はオブジェクト指向ってしっくりこないんです! -本文-
staticを使えば、わざわざインスタンスを作る必要などない「メンバー関数をstatic宣言すればインスタンス宣言をしなくてもいい」ということ知ってからは、メンバー関数を従来のファンクションのように使っている。
独自にクラスを作る必要などない。クラスは使うものだ。作るものではない「自分でクラスを作ってオブジェクト指向っぽいことをしている」なんてことはまったくない。
オブジェクト指向など、実業務では使いものにならない!オブジェクト指向は、結局のところホントにモノ(オブジェクト)に使われている記法、例えばGUI コンポーネント、データベース、ファイルなどであって、プログラムのアルゴリズムとは無関係のものである。
 
高慢と偏見最終話実はオブジェクト指向ってしっくりこないんです! -コメント欄-
私はT大学大学院卒だ私は学部は東北大学で大学院が東工大です。
あなたはSIerだろう。私は客側の人間だ。客の言うことは絶対だ私はIS部門の人間なんです。SIerの客なんですよ。私に嫌われたらどうなりますか?

類似点は他にもあるのですが、これを見れば、「高慢と偏見の最終話」にあるスリーピーチ(三浦さん)のブログのモデルは、『実はオブジェクト指向ってしっくりこないんです!』であり、スリーピーチ(三浦さん)はみながわさんということを示唆していると受け取られても仕方がないでしょう。実際にそのように受け取っている方もいらっしゃいます。
「高慢と偏見の最終話」のコメント欄からいくつか引用してみましょう。

toanna 2011年2月21日 (月) 23:33 (一部引用)
まとめサイトしても読める!!
まとめサイトというのは『実はオブジェクト指向ってしっくりこないんです!』の炎上部分を示唆していると受け取れます。

音速の気功師 2011年2月24日 (木) 01:27 (一部引用)
あれが論外なのは言うまでもない事実です。それは認めます。
あれというのは誰かは指摘しなくても解るでしょう。

通して読みました 2011年8月 9日 (火) 19:04 (一部引用)
ただ、途中からコメント欄に書いてある(ネタバレ?)を
見ていて、純粋に読み物として読んでいて、つまらなくなってしまいました。
内容がコメント欄とかぶってくるのか、単に例の人を貶めるような内容として、
読み進んでしまったのが、自分としての反省です。

さて、このコメントでは『例の人を貶めるような内容として、読み進んでしまったのが』と書かれています。
貶めるというのは、本文中の

たまに別のWebサイトのコメント欄に、オブジェクト指向批判を書くこともあった。当然、技術的な裏付けも何もない、思い込みによる批判だから、正論で完膚なきまでに叩きのめされてしまう。正面から議論を展開できるだけの知識がないから、スリービーチさんにできることは、「その日本語はおかしい」とか「若い人はすぐに感情的になるから議論にならない」などと、負け惜しみを書くことだけだった。

という書き込みの他、

ソースを調査したコンサルティング会社のエンジニアは、あまりに効率の悪い前時代的なコーディングに絶句したらしい。そりゃそうだろう。私だって、事前知識なしであのソースを見たら驚く。

 「時代錯誤も甚だしい」

 「保守性というものをまった考慮していない」

 「最低でも6カ月を要する、根本的な大改造が必要」

 コンサル会社からの報告書には、このような指摘が続々と連なっていたという。調査の過程で、開発方針が途中で大幅に変更された事実も明らかになり、三浦マネージャは連日のように、専務やら常務やらの前で釈明に追われることとなった。平良さんら何人かの常駐メンバーも事情を聞かれたが、三浦マネージャを積極的に擁護しようとする人はいなかったようだ。中には、あからさまに批判するメンバーもいたらしい。

とか、締めの文章

 高学歴で長い経験に自信を持つエンジニアは他人の話を聞かなくなる、というのは広く世に知られた真理の1つである。

 三浦技術担当マネージャは、そのようなエンジニアの生きた見本のような人だった。

とか随所にあります。その他いちいち抜き出すことはしませんが、『高慢と偏見の最終話』の後半部分、『そして数カ月後。』からを読んで頂ければ解るでしょう。

ちなみに文中にあります『ポリモリズム』は『ポリモーフィズム』の間違いです。みながわさんは『実はオブジェクト指向ってしっくりこないんです!』のコメント欄でポリモーフィズムを数回、書き間違えておられました。それをもじったものだと推測されるでしょう。


これでは三浦マネージャ=みながわ氏が成立し、特定の人物を貶める内容になっているのではないでしょうか?

その他の例(ポリモーフィズムの例)

この小説は、他にも『三浦マネージャ=みながわ氏』をうかがわせると思われるエピソードがあります。
高慢と偏見(3)コードレビューは踊る の『List userNameList = new ArrayList();』にまつわる論争部分です。

これは、以下のコメント欄の論争から取られていることがうかがわされるでしょう。

http://el.jibun.atmarkit.co.jp/densol/2010/08/post-8443.html オブジェクト指向。教科書と現実のはざまで
このコラムのコメント欄にみながわさんが書き込んでいますが、いきなりAC/DCさんが、みながわさんを批判し、コラム主から注意を受けています。

さて、みながわさん、AC/DCさんどちらがマナーのある人でしょうか?

もちろんですが、みながわさんがstaticが・・・と言い出したらそのときにまた反論すればよろしいかと思います。

さらにflatlineさんが

>たとえば、Javaで、
>List userNameList = new ArrayList();

とコラムの趣旨とは異なる議論を吹っかけています。
みながさんもこれに対して

>ArrayList list = new ArrayList();
>のように基底クラスを使わない例が一般的です。


と応戦してしまっています。

ここで、この"一般的"の趣旨について補足します。まず
 List userNameList = new ArrayList();
の書き方はjavaが出た当時はある意味画期的だったのですが(当時そういう風に紹介している書籍もあった)、他の言語では、良くない例とされています。根拠は「Effective STL」に書いていますしCMPさんと同名の方や他の方も「高慢と偏見(3)コードレビューは踊る」のコメント欄に同様の趣旨のことを書かれています。要するにArrayListとLinkedListの概念を統合・抽象化(Listインタフェース)しても意味がないのです(ほぼゴミ)。そのような訳でして実は、C++/STLや後から出てきたC#ではみながわさんが言ったような書き方 し か 出来ません。
これに"一般的"という言葉を使うことが適切かどうかという批判はあるかと思いますが、java以外の”一般的な”オブジェクト指向言語という意味ではまぁOKでしょう。

flatlineさんは「一般的です」という断定の言葉尻をとらえるのではなくてみながわさんが言っていることの意味(というかその背景)をもっと深く、理解する必要があります。

このような状況下で、flatlineさん個人の感想として、みながわさんのことを『話を聞かない人』と思うのは構いませんが、客観的にみると?と思うわけです。
もちろん、みながわさんも『C#では一般的』と言えば話が進んだのでもう少しコメントするときに考えて頂ければとは思いました。

そういう意味では『どっちもどっち』ということになります。

以上を踏まえて、「高慢と偏見(3)コードレビューは踊る」を読むと、ものすごい誤解から一方的に書かれていることが分かるかと思います。私には何が面白いのかまったく分かりませんでした。

(主人公目線で)みながわさんがオブジェクト指向が解らないから『ArrayList list = new ArrayList();』と書かれていますが、ちがうことが解りますよね。
ちなみにこの「高慢と偏見(3)コードレビューは踊る」でも、

 「ポリモーフィズムです。ポリモリズムでもポリフォリズムでもありません」

 三浦マネージャの顔色が一瞬変わったが、すぐに薄ら笑いを浮かべた。

とポリモーフィズムの間違いのエピソードが出てきています。



以上、『高慢と偏見』がみながわさんのコラムおよびその他のエンジニアライフのコラムの論争のパロディであることをうかがわせるような内容となっています。
このようなパロディは他にもあり、当時の論争を知らない人にはぱっと見て解らないかと思いますが、『高慢と偏見』の本文とコメント欄をみれば、どういうことが解るかと思います。


エンジニアなら技術的な論争があった場合、あくまでも技術的かつ論理的に反論しましょう。相手が聞く耳を持たないと判断する前にもう一度、ご自身の説得力に問題がないか検証しましょう。論争相手を貶めるようなことはエンジニアとしては慎みたいものです。

2012/11/03 加筆、修正
2012/11/06 修正
2012/11/14 修正 質疑応答をアップしました
2012/11/18 コメント欄での指摘を受け、全面改定
2012/12/02 修正
2016/01/31 関連記事をアップしました
2012-11-01 | コメント:66件



ダジャレクラウドのリリース

以前、ブログに書いていたダジャレクラウドですが、晴れてリリースとなりました。
 
遊び方ですが、『ダジャレ・リサーチ』というテキストボックスにキーワードを入力し、検索ボタンをクリックするという至ってシンプルなものになります。
ちなみに最近私が面白いと思ったものは『オリンパス』で検索したものです(まぁ少々ブラックですが・・・)。
 
ソフトウェア開発の常なのですが、このプロジェクトも遅延しましたが何とか無事にお披露目できるようになりました。
あまり赤裸々に書くのも如何なものと思われるかと思いますが、こういった経験は私自身も肥やしになるのと、あまり外には聞こえてこないもので興味深いと思いますので、適当にフィクションを入れつつ記事を書いてみます。ので以下はフィクションと思って頂ければと思います。
 
■ プロジェクトの目標がはっきりしているか?ぶれないか?
 もともとHack4JPという震災復興プロジェクトの1つとして立ち上がりましたが、『だじゃれ』と『震災復興』というあまりにもかけ離れたお題に対して一部のメンバーが動機付けに苦労し余計な時間を費やした点が上げられます。
つまり、プロジェクトだじゃれという不謹慎なものに対して負い目を感じ、それに対して大義名分をつけようとして『開発を行う』というエンジニアの本分を忘れてしまい結局開発に手が付かなかった点があります。
結局は、『ダジャレで被災者を応援しよう』という当初の目標に落ち着き混乱が収拾されました。
 
■ボランティアに対するスタンスの違い
 私はこういうボランティアは始めてなのですが、メンバー間のボランティアに対する認識の違いがありました。
私の中では、参加条件が『プロが無償でする』であり、その方が『出来る範囲で出来ることをする』という認識でいました。
『プロが無償でする』というのはどういうことかと申しますと速い話がボランティア(タダ)といってもいい加減な仕事をしてはいけないということで、例えますと英語ができない人が通訳のボランティアをやっては逆に迷惑でしょう。ということです。
つまりソフトウェア開発プロジェクトなら開発ができる人が開発を行うということなります。
当たり前ですが、どのようなソフトウェア開発プロジェクトも開発者だけ回りません。リーダーやプランナーの方とう様々な役割をもった方も必要です。チームとして活動する場合はそういったリーダーやプランナーとして仕事ができる人も参加する必要があるでしょう。

プロジェクトの混乱の1つにこのスタンスの違いがありました。つまり、無償で作業をするという認識は一致していたかと思いますが、「プロ」の部分が抜けておりました。先ほどの英語の例でいいますと英語がしゃべれないけど通訳のボランティアをするといった具合です。もっとも明らかにしゃべれないなのらヤメトケで済みますが、微妙な場合は線引きが難しくこれが混乱の元になりました。
『できるかどうか解らないがやってみる』というのはありかと思いますが、その場合は周りに迷惑にならない程度に『やっぱりできませんでした』とか『ここまでならできました』とかの報告が欲しいものです。
ボランティアに限った話ではないですが、厄介なのが充分な能力をもっていないが自分はできると思っていたり、『出来ません』と言えずに引くに引けないようになってプロジェクトが停滞しました。

この点のもう1つの問題が、メンバーの意識として『出来る事をする』ではなく『したい事をする→出来ないことをやろうとする』になってしまう点です。これが復興支援という大義名分と融合して混乱に拍車をかけた部分があります。当たり前ですが、ほとんどの日本人(世界の人)が東北の方の1日でも速い復興を願っています。前項とも絡んでくるのですがその思いが空回りして、したい事をプロジェクトとして実行させようとし結果として、出来ないことをやろうとすることになっていました。

■ボランティアに対するスタンスの違いとプロジェクト運営の経験不足
 そもそも論としてボランティアだからモノを完成させる必要はないという認識の方もいらっしゃいました。こういう考え方自体は悪くないかと思いますが、少なくとも依頼者は完成させて欲しいと思っていますし、また、メンバー内にも完成させたいと思っている方も当然居ました。この場合は明らかに完成に向けて作業を行う必要があるかと思いますが、そういった中でご自身の意見を優先される方がいらっしゃいました。
個人の意見がプロジェクト運営上妨げになるという場合、その点については当然調整を行う必要があるでしょう。つまりある部品の開発者であったが興味を失ったので開発はもう終わりにしたいと思った場合、別の開発者に任せるようにする必要があるでしょう(本来ならある程度完成させてから抜けるのが筋だと思いますが・・・)。それをプロジェクトとして完成させる必要がないとされると周りの者が迷惑をこうむります。

■文化の違う方とのコミュニケーション
 立場の違う人達が集まると波風が発生するもので、上記の認識の違いやら、果ては言葉遣いや段取り等の違いから波風が立ちました。
このプロジェクトですが見た目が簡単で面白そうなのでエンジニアでない方も入ってこられました。
それ自体は悪くはないですが、例えば、システム開発で発注者の立場の人と受注者の立場の人がボランティアで一緒になるとほぼ立場が逆転します。なぜなら発注者というのはお金という力を使って受注者をある意味支配していますが、ボランティアベースになるとお金という力がなくなるので、別の何かで開発者の方と協力しあわなければなりません。
こういったところでコミュニケーション不足が一部にありメンバーの不満が高まったこともありました。
この点については幸いにも粘り強く話しをしたら誤解であったことが解り、開発者でない方のプロジェクトに対する貢献方法(広報活動だったりプロジェクトの企画だったり)を考えることにより作業が進行できたので、1つ収穫になりました。

とまぁ色々問題が発生しましたが齢40を過ぎていい社会勉強になりました。

2011-11-11 | コメント:0件



プログラマ35歳定年説を検証する part1 - TopCoder

気が付けばまたもやブログの更新がおろそかになっていたので近況がてら更新します。
ちなみに、スマートフォンはもういやだ!と思っていたのですが、業務命令でiPhone4S(ア・イ・フ・ォ・~・ン)を予約したのですが1ヶ月待ちとのことで今しばらくはX01Tとのお付き合いになります。まぁ手に入ったらまたレポートなんぞをしてみます。
ADP1周年記念やSQLのパフォーマンスについてのまとめページが進んでいませんし、ダジャレクラウドとか地味にその他に書くことがあるのですが、最近ちょっと関心を持った話題を書きます。

今から20年以上前にまことしやかに囁かれた『プログラマ35歳定年説』という仮説がありまして、まぁ『35歳ぐらいになったらプログラマとしては役に立たなくなる』という感じで使われたりします。まぁ一種の都市伝説のようなものですが、実際に信じている人も多いようで ぐぐる グーグル先生で検索すると未だに肯定するような記事も出てきます。
私は今年で40歳を超えるのですが、いまだに開発を行っていますし何よりこのブログが『俺は使える事を』証明しているとも思わなくもないですが、もっと客観的に証明する手段として、TopCoderというものがあると思いましたのでそのお話でもしてみます。

TopCoderというのは、プログラミングコンテストの一種で、競技プログラミングとも呼ばれており、制限時間内(75分)にお題にそったプログラムを組むというものです。
問題は、簡単・普通・難しいと3つ出題され、それぞれ難易度とプログラミング時間によってポイントが付き、そのポイントを競うというものです。
単純にプログラミングをして終了ではなく、プログラミング後、他のメンバーが作成したプログラムを参照できバグを発見したら(バグを現出させるテストケースを与えれば)、別途ポイントがもらえます(チャレンジという)。
そのようにやってポイントを稼ぐと、レーティング(通算ポイントのようなもの)が貰え、そのレーティングによって順位付けがされるというものです。

私の現在のレーティングは1391になりますが、これは9138人中の2047位(全世界)、766人中の141位(日本)らしいです。
この順位で私が使えることが証明されたかどうかは実はいまいちなのですが、私より順位が下の人には某一流大学の人たちもいますので、そういう意味では『まだまだ若いもんには負けていない』ということはいえるかと思います。もっとも私より上位にも某一流大学の方が居るので一概に某大学生に勝ったとはいえません。
レーティングが上位になると『レッドコーダー』と呼ばれるようになります。なぜレッドかと言いますとレーティングによってIDが上から、レッド、イエロー、ブルー、グリーン、グレイで色分けされる関係でそう呼ばれるようです。私の現在の色はブルーになります。参加しだして間が無いのでなれていない面もありますので、精進を重ねレッドコーダーになれば、晴れて私も使えるプログラマということが証明されるかと思います。

75分という極めて短い時間でプログラムを作成するので本当の実力の一部分しか計測できないでしょうが、問題自体は非常に良く出来ているとも思いますし、何より自分の実力が客観的に判るので腕に覚えのあるITエンジニアの方は是非挑戦してみては如何でしょうか?
2011-11-07 | コメント:0件



JOINのパフォーマンスについての考察2(リレーションとの関係2)


ちょっと間があきましたが、JOINのパフォーマンス関連の続きになります。
前回、JOINのパフォーマンスについての考察(リレーションとの関係)でJOINを行った結果、データが非正規化するとその非正規化の度合いによってパフォーマンスが下がるという話をしました。
前回の記事では、1対nの結合ではJOINを外す(単純なSQLに分割してホスト言語側で結合させる)ということで、定性的な話しかしていませんでしたが、幾つか実験を通して、もう少し定量的な話をしてみます。
『たかがJOINで、なぜこねくり回すのか?』と思われるかもしれませんが、こういう実験&考察というのは意外に行われていないかと思います。私自身定性的なことは理解していたつもりでしたが、実際に実験を行うと色々と発見がありますので、記事にしてみます。
大切なことは解った気になることではなく真実を追究する姿勢で、先入観を持たずにきちんと実験を行いパフォーマンスに対する感性をみがくことは大切かと思います。

今回、調査するアルゴリズムについて

今まで何回か実験してきましたが、実験で使用してきたアルゴリズムについて説明します。

1.SQLでJOINを行う。

SELECT Price.CODE, RDATE, OPEN, CLOSE, NAME
FROM Price INNER JOIN Company ON (Price.CODE = Company.CODE)
という風にSQLでJOINを行います。普通の処理になります。

2.ホスト言語側でJOINを行う(キャッシュ付のネステッドループJOINを行う)

 1.のSQLを以下のように分割します。
(1) SELECT CODE,RDATE,OPEN,CLOSE FROM Price
(2) SELECT NAME FROM Company WHERE CODE = ?

(1)のSQLを実行して結果を取得しますが、NAMEについては(2)のように再度SQLを発行します。
ここで、単純にPriceテーブルの全ての行に対して(2)SQLを発行するのではなく同じ結果をキャッシュして同じCODEの場合はキャッシュからデータを取得するようにします。
 

3.ホスト言語側でJOINを行う(ハッシュJOINを行う)

1.のSQLを以下のように分割します。
(1) SELECT CODE,NAME FROM Company
(2) SELECT CODE,RDATE,OPEN,CLOSE FROM Price

(2)のPriceテーブルからのデータの取得に先立ちまして、(1)でComapnyテーブルから全てのデータを取得しておきます。
多くのDBMSで行っているハッシュ結合を真似ています。

1対nの2つのテーブルのJOINにおけるパフォーマンスモデル式

続いて、各アルゴリズムのパフォーマンス(実行時間)のモデル式を示します。
ここで、
n : Priceテーブルの行数
m : Companyテーブルの行数
c10,c10,c20,c21,c22,c23,c30,c31,c32 : 比例定数
になります。

1.SQLでJOINを行う

1.のパフォーマンスのモデル式は以下のようになります。

c11 * n + c10

 Priceテーブルの行数に比例した時間で結果を取得できます。ここでc11は比例定数であり、C10はオーバーヘッドにあたります。

2. ホスト言語側でJOINを行う(キャッシュ付のネステッドループJOINを行う)

 2.のパフォーマンスのモデル式は以下のようになります。

c21 * n + c22 * m + c20

 Priceテーブルの行数に比例した時間と、Companyテーブルの行数に比例した時間およびオーバーヘッドの合計になります。
 『c22 * m は c22 * n * m になるのでは?』と思われるかと思いますが、キャッシュのおかげでこのようになります。
また、「1.SQLでJOINを行う」と比べますと、c22 * m と余計な項が付いていますので、

SQLでJOINした方が速い

と早合点される方がいらっしゃるかと思いますが、JOINのパフォーマンスについての考察(リレーションとの関係)で述べたことは、c11とc22の定数値の差異となって現れてきます。

3.ホスト言語側でJOINを行う(ハッシュJOINを行う)

 3.のパフォーマンスのモデル式は以下のようになります。

c31 * n + c32 * m + c30

 面白いことですが、形式的には「2. ホスト言語側でJOINを行う(キャッシュ付のネステッドループJOINを行う)」と同じになります。
ちなみに、[ADP開発日誌]SQL(JOIN)の実行パフォーマンスについて2011 にあります、「SQLの発行回数のオーバヘッドはどこにいったんや?」と思われるかもしれませんが、それはc32とc22の差異に出てくるということになります。

実験と結果

 今回の実験では、nの値を変えながら実行時間を計測することにより、各モデル式の定数を求めます。求めるといってもグラフを書いて状況を観測します。厳密には回帰分析とかを行うことになるでしょうが、グラフが直線になることと、nが増えたときの傾向をつかめればよろしいかと思います。
アルゴリズムの教科書ではオーダーという概念があり、オーダーでは定数を求めることは無意味とされています。つまり上記のアルゴリズムは論理的には違いがなくどれも一緒ということになります。
つまり、2倍や3倍の差はあまり意味がないということですが、もっとも、実際の現場ではこのような差にも敏感になるので、きちんと計測して値を出すことになります。
また、今回はmは固定(約2000)で行っています。mが変動したときにどう変わるのかも興味深いですが今回は、m << n ということで結果にはあまり影響しません。

先ずは、結果から、
Priceテーブルから取得する行数を変えながらSQLを実行(単位ms)
0行373,740行1,172,191行2,002,749行4,671,568行
1.SQLでJOIN71810,01529,93852,329119,192
2.キャッシュ付のネステッドループJOINを行う67110,46930,17249,814116,770
3.ハッシュJOINを行う2,82811,42229,79749,845110,988

つづいて、グラフを以下に示します。

縦軸が時間で、横軸が行数(n)になります。グラフをみますとPriceテーブルの行数(n)が増えると「1.SQLでJOIN」より、「2.キャッシュ付のネステッドループJOINを行う」や「3.ハッシュJOINを行う」の方が速くなっていくことが解るかと思います。

パフォーマンスにシビアになる時は、往々にしてnの行数が増えるような場合にあたるということになります。その場合は1より2や3を選択した方がよいということになります。

もっともグラフを見て解るとおり差はあまりないので、通常はやはり普通にSQLでJOINを行い、パフォーマンスを稼ぎたくなったら2や3を検討するということになるでしょう。

2011-09-29 | コメント:0件



JOINのパフォーマンスについての考察(リレーションとの関係)

コメントを頂いたのですが、ちょっと返し方が悪かったのか音信普通になりましたので、改めてJOINのパフォーマンスについて考察してみます。

1対n結合の場合、JOINとは正規化データから非正規化データを作り出す操作になる

RDBのテーブルは、きちんと設計されていれば、正規化されています。つまりデータに重複がなく容量の面で効率的になっています。ここで正規化データとはあくまでもRDBにとって効率的というだけでそれ以上のものではありません。一方で人間が理解しやすいデータ形式は必ずしも正規化データというわけではなく、往々にして非正規化されたデータの場合があります。
JOINを行うということは正規化されたデータを非正規化データに戻す操作ということに相当します。つまり、効率のよいデータから人間にとって理解しやすいデータ形式に戻す操作になります。JOINは正規化されたデータから非正規化という効率の悪いデータ形式に変換する操作になります。
SQLでJOINを行い、その結果を取得するということは何らかの非効率な行為が行われているということがわかるかと思います。
RDBのコピーを行おうと考えた場合、わざわざJOINなどせずに、テーブル毎にコピーを行おうとするでしょう。RDBからデータを取り出すとき同様に正規化された単位でデータを取得した方が有利な場合があるということは理解できるかと思います。

RDBでは正規化データから非正規化データを作り出す方が非正規化データから正規化データを取り出すより効率的

先ほど、JOINは非効率といいましたが、なぜRDBでは効率の悪いJOINが行われるのでしょうか?
理由は簡単で、RDBの理論では、
・非正規データ から 正規データ を作る
操作より
・正規データ から 非正規データ を作る
操作の方が効率的と考えられているからです。非正規データから正規データを得るにはグループ化を行います。つまりGROUP BYを行う必要がありますがこれはつまりソートを行った上に重複したデータを圧縮することに相当します。一方でJOINはデータの検索に相当します。例外はありますが検索の方がソート&圧縮より効率的なのは理解できるでしょう。
さらに、正規化データは非正規化データより更新が容易ということもあります。
つまり、関係データベースの世界では正規化されたデータは非正規化されたデータより効率がよいと考えられています。ちなみに、この認識が間違って拡大解釈され、『SQLは効率がよい』という誤解が生まれたと想像されます。

1対nの結合で一方のレコードサイズが小さいとき、2つのテーブル間の単純なJOINは効率的、だがデータの出力が非効率

FROM table_a INNOR JOIN table_b ON (table_a.table_b_ID = table_b.ID)
のSQLがあるときに、
table_aがマスターを参照するテーブルで、table_bがマスターテーブルと仮定します。つまりtalbe_aとtable_bが1対nで結合されており、さらにtable_bがメモリに入る場合、JOIN自体のコストはほとんどかかりません。
2011年現在、サーバーに搭載されるメモリ容量が数十GBのオーダーになります。一方でマスターテーブルの容量は多く見積もっても数百万件のオーダーになり、各データを多く見積もって1KBとしてもマスターテーブルのデータ容量は数GBのオーダーとなります。実際にはJOINに必要なデータのみメモリにおいた場合、必要なデータは1桁も2桁も減ることになります。結果として1対nの結合ではほどんどの場合、マスターテーブル側はメモリに乗ることになり、JOINにおいてマスター表の操作は高速に行えます。
しかし、1対nの結合では、結果を取得する場合に、結果データが非正規になる為に非効率になります。
この場合、JOINを分割して、呼び出し言語側でJOINした方が理論的には効率的になります。実際どこまで効率的になるかは分割による複数回のSQLの呼び出しのオーバヘッドと繰り返しデータの量に左右されます。

1対1結合の場合は、JOINは出力も含めて効率的になる

1対1結合の場合は、結果データも正規化しているのでJOINは効率的になります。JOIN自体が効率的に行えるかどうかはデータ量やデータ(または結合キーのインデックス)が整列されているかどうかによります。

結論

以上のように、扱うデータの性質によってSQLでJOINさせる方がよい場合とSQLではJOINさせない場合の方が理論的に速くなる例を示しました。
結合の種類が1対nの場合、JOINを行うとデータ非正規化し、容量が増えるので出来るだけJOINを遅らせるテクニックが有効になる場合があります。
実際にどのような状況のときにJOINを遅らせたほうがよいかですが、マシンのスペック、ネットワークの環境等に依存しますが、傾向として行数が増えた場合や1対nのJOINの数が増えるとJOINを遅らせる方が有利になります。このような場合でパフォーマンスに問題が発生した場合にJOINを遅らせるテクニックを検討されると上手くいく可能性が高まります。
一方で、結合の種類が1対1の場合、データは非正規化しないので、SQLの発行の段階でJOINを行えば有利になります(JOIN自体のコストはまた別の話になります)。

2011-09-06 | コメント:0件
Previous Page | Next Page