SQLer 生島勘富 のブログ

RDB・SQLの話題を中心に情報発信をしています。

SQLは最も高級言語2

 SQLは、現在、普及している言語の中で最も高級な言語です。言語は高級になればなるほど人間に近づきシンプルにやりたいことが実現できる反面、実行速度は遅くなり、できることも限られます。

 最も低級なマシン語と≒のアセンブリ言語であれば、コンピュータでできることは何でもできます。それが高級言語のJavaになれば、Java VMがなければお手上げになり、Java VMで処理可能なことしかJavaではできません。スクリプト言語はインタープリタがなければ動かない。もちろん、更に高級な言語のSQLは、DBエンジンがなければ何もできませんし、できることはDB内の処理に限られてしまいます。

 言語は、低級なほどできることが多く、高級ほど特定のことしかできなくなるわけです。

 一方で、低級な言語ほど、杓子定規に、あらゆる条件を指示しないとコンピュータは動かなくなり、高級な言語ほどアバウトな命令で、望んだ結果が得られます。

 つまり、理論値としては(おのおののスキル差をなくせば)高級言語ほど工数が掛からない反面、パフォーマンスは遅くなり、高級言語ほどそれだけでできることは限られてきます。

 トレードオフの関係は、
    工数 <−> パフォーマンス・低級(マシンに近い)処理の実現

 となります。例えば、OSのカーネル部分やそれに近い部分は、低級言語のアセンブリ言語が採用されることが多くなります。マシンに近い処理として、デバイスドライバーも昔はアセンブリ言語が採用されていましたが、マシン自体が速くなったことによって「パフォーマンス(ファイル容量のときもあったが)」という価値が下がったため、C言語やC++を採用することが多くなっています。

 しかし、できない人を考慮すれば、工数が無限大になるのでトレードオフの関係は成りたちません。つまり、もし、このトレードオフの関係が成りたたないと感じるのであれば、いずれかのスキルが足りないということを証明してしまいます。

SQLの最も高級な部分

 SQLのどこが高級かというと、アルゴリズムがないところです。

 例えば、

    SELECT * FROM TABLE_A WHERE KBN = '1';

 というSQLを見てみましょう。

 この単純なSQLでも、KBN(TABLE_A_IDX)にインデックスがあった場合、処理イメージはおよそ以下の2つになります。(あくまでイメージです)

Aパターン
 readSet = TABLE_A_IDX.Seek('1');
 
 for (Object row : readSet){
   key = row("KEY").Value;
   returnSet.add(TABLE_A.Seek(key));
 }
 
 retun returnSet;

Bパターン
 for (Object row : TABLE_A){
   if(row("KBN").Value == "1"){
     returnSet.add(row);
   }
 }
 
 retun returnSet;


 どちらのアルゴリズムでデータを取得するかというのは、オプティマイザ任せで、SQLではアルゴリズムを書かなくても欲しい結果を最適なアルゴリズムを使って得ることができます。オプティマイザは、コンパイル前に、Aパターン、Bパターンのいずれででコンパイルするか、データの分散を考慮して決めます。複雑な処理になったら、数十、数百のパターンのアルゴリズムの中から一つを選ぶことになるでしょう。

 このように、人間が書いたソースから、データ(状況)に応じて違ったアルゴリズムを作り出しコンパイルしてくれる言語は、普及している言語の中ではSQLだけで、SQLは最も高級言語なのです。

 反面、そのアルゴリズムを作るという処理は、非常に複雑で重い処理になります。

 RDBMS(SQL)を使うと、その重い処理を通すことになるため、RDBMS(SQL)は大変遅いのです。その遅いRDBMSを敢えて使う以上は、SQLを使いこなさねばプロとは言えないし、より低級の言語でアルゴリズムを書きたいというならば、RDBMSの重い処理をショートカットしなければ意味がない。つまり、NoSQLを採用する必要がある訳です。

 Javaのプロジェクトで、どうしてもパフォーマンスが出ない部分や、どうしてもJavaではできないマシンよりの処理をC++で書くことはあるでしょう。しかし、C++でメインのアルゴリズムを書き、ボトルネックの部分でJavaのモジュールを呼ぶというのは、普通はあり得ない。そんなことをするならとてつもなく馬鹿です。

 ところが、SQLにおいてはそのような馬鹿げた構造が普通に見られる。つまり、アルゴリズムをJavaなどで書きながら、なおかつ、データアクセスにSQLという重い高級言語を使っている。それが「正しい」と主張するのは、「自分はとてもプロとは呼べない馬鹿です」と宣言しているようなものですが、そういう連中が絡んで来るのは毎度のことながら、あきれ果てるしかない。

何とトレードオフするか。

 低級言語と高級言語をひっくり返すと、理論的にはパフォーマンスと工数がトレードオフの関係になる。何度も繰り返しているとおり「SQLを使わない方針」というのであれば、KVSなどのNoSQLを利用する必要があるのですが、RDBMSを使いながら「SQLを使わない(単純なSQLだけを使う)方針」というのは、何と何をトレードオフしているのか?

 例えば、現実問題として、現在のシステムをアセンブリ言語で書くことは不可能でしょう。

   遅い + 安い(価値がある) > 速い + 高い(高すぎて価値がない)

 となるからです。どちらも顧客に対する価値をトレードオフして選択している。現状では、アセンブリ言語で速くなるという顧客に対する価値は、増える工数(システムの価格)よりも遙かに小さいので、現実的には不可能と判断されるわけです。無尽蔵の工数を掛けて良いのであれば、アセンブリ言語にできないことはありませんし、OSのカーネルなどは工数が掛かっても、アセンブリ言語で作ることになるでしょう。

 RDBMSを使いながら「SQLを使わない(単純なSQLだけを使う)方針」というのは、本来は、

   遅い + 高い(価値がない) < 速い + 安い(価値が高い)

 となる。理論的には「SQLを使わない」ということに価値はないが、できない人に取っては

   遅い + 高い(価値がある) > スキルが足りずできない(価値はゼロ)

 この場合、右辺に乗るものは技術者の都合しかない。つまり、顧客に対する価値と、技術者のスキル不足をトレードオフしている。そんな主張をしては技術者ともプロとも言えない。

 現実問題として、できないんだから仕方ないのですけれど、いつまでも言うべきではないでしょう。

SQLはスキル差が大きすぎる。

 現実問題としてできない人が非常に多い。であるなら、できる人とできない人担当を分けるしかないのです。SQLができる人は、SQLを担当し、SQLができないながらもプロでいるということは、他の言語はできるのでしょうから、他の言語だけを担当すればいい。

 SQLと他の言語は考え方が全く逆になるので、同じ人が担当するのには無理があるのです。

 SQLができないことが馬鹿なのではないし、それ自体に何も問題はありません。

 しかし、RDBMSを使いながら「SQLを使わない(単純なSQLだけを使う)方針」というとんでもない馬鹿な方針を立てるのは、SQLができない人達です。そのとんでもない方針を立てることが馬鹿げているのです。

 他の言語もできなければシステムはできない。どちらも必要です。

 しかし、SQLとは何でどう扱うべきか、ということは、全員が理解する必要があるでしょう。その理解がないために、システムのグランドデザイン、方針をお馬鹿な方向へ向けるのであれば、大馬鹿者としか言いようがありません。