要するに、私はあなたのCTOに同意します。おそらく、スケーラビリティを犠牲にしてある程度のパフォーマンスを得ることができます(これらの用語がわかりにくい場合は、以下で明確にします)。私の2つの最大の心配は、保守性と水平方向に拡張するオプションがないことです(あなたがそれを必要としていると仮定して)。
データへの近接性: 一歩後退しましょう。DBにコードをプッシュする理由はいくつかあります。最大のものはデータに近いことだと主張します-たとえば、計算が少数の値を返すと予想しているが、これらが何百万ものレコードの集約であり、何百万ものレコードを(オンデマンドで)送信する場合他の場所に集約されるネットワークは非常に無駄が多く、システムを簡単に停止させる可能性があります。そうは言っても、データの近接性を他の方法で実現できます。基本的には、キャッシュまたは分析DBを使用して、集計の一部を事前に行います。
DB内のコードのパフォーマンス:「実行計画のキャッシュ」などの二次的なパフォーマンスの影響を議論するのはより困難です。間違った実行計画がキャッシュされた場合、キャッシュされた実行計画は非常に否定的なことがあります。RDBMSに応じて、これらを最大限に活用できますが、ほとんどの場合、パラメーター化されたSQLをあまり使用しません(これらのプランも通常キャッシュされます)。また、ほとんどのコンパイルされた言語またはJITされた言語は、基本的な操作および非リレーショナルプログラミング(文字列操作、ループなど)について、通常は同等のSQL(T-SQLやPL / SQLなど)よりも優れたパフォーマンスを発揮するため、 JavaやC#のようなものを使用して数値計算を行った場合、そこに何かを失うことはありません。きめ細かい最適化も非常に困難です-DBでは、多くの場合、唯一のデータ構造として汎用Bツリー(インデックス)を使用します。公平を期すために、実行時間の長いトランザクションやロックのエスカレーションなどを含む完全な分析は、本を埋める可能性があります。
保守性: SQLは、その目的のために設計された素晴らしい言語です。アプリケーションロジックに最適かどうかはわかりません。私たちの生活を耐えられるものにするツールとプラクティスのほとんど(TDD、リファクタリングなど)は、データベースプログラミングに適用するのが困難です。
パフォーマンスとスケーラビリティ:これらの用語を明確にするため、私はこれを意味します。パフォーマンスとは、単一の要求がシステムを通過する(そしてユーザーに戻る)ことを期待する速度です。これは、多くの場合、通過する物理層の数、それらの層の最適化などによって制限されます。スケーラビリティとは、ユーザー/負荷の増加に伴ってパフォーマンスがどのように変化するかです。中/低のパフォーマンス(たとえば、リクエストに対して5秒以上)がありますが、素晴らしいスケーラビリティ(何百万人ものユーザーをサポートできる)があります。あなたの場合、おそらく良いパフォーマンスが得られますが、スケーラビリティは物理的に構築できるサーバーの大きさによって制限されます。ある時点で、その制限に達して、シャーディングのようなものに向かわざるを得なくなります。シャーディングは、アプリケーションの性質によっては実行できない場合があります。
時期尚早の最適化: 最終的に、時期尚早に最適化するという間違いを犯したと思います。他の人が指摘したように、他のアプローチがどのように機能するかを示す測定値は実際にはありません。さて、理論を証明または反証するために常に本格的なプロトタイプを構築することはできません...しかし、一般的に、パフォーマンスのために保守性(おそらく最も重要なアプリケーション品質)を犠牲にするアプローチを選択することを常にためらいます。
編集:肯定的なメモでは、場合によっては垂直方向のスケーリングがかなり遠くまで伸びることがあります。私の知る限り、SOは単一のサーバーでかなり長い間実行されていました。1万人のユーザーにどのように一致するかわかりません(システムで何をしているのかによって異なります)が、何ができるのかがわかります(実際には、より印象的な例、これはたまたま人々が簡単に理解できる人気のあるものです)。
編集2:他の場所で提起されたいくつかのことを明確にし、コメントするには:
- 再:原子の一貫性-ACIDの一貫性は、システムの要件である可能性があります。上記は実際にはそれについて議論していません。ACIDの一貫性は、すべてのビジネスロジックをDB内で実行する必要がないことを理解する必要があります。そこにある必要のないコードをDBに移動することにより、DBの残りの物理環境で実行するように制約します。DBの実際のデータ管理部分と同じハードウェアリソースを奪い合います。コードだけを他のDBサーバーにスケールアウトすることについて(実際のデータではありません)-確かに、これは可能かもしれませんが、ほとんどの場合、追加のライセンスコストを除いて、ここで正確に何を得ていますか?DB上にある必要のないものは、DBから離して保管してください。
- Re:SQL / C#のパフォーマンス-これは興味のあるトピックのようですので、議論に少し追加しましょう。もちろん、DB内でネイティブ/ Java / C#コードを実行できますが、私が知る限り、それはここで議論されたものではありません-T-SQLのようなものとC#のようなものの典型的なアプリケーションコードの実装を比較しています。過去にリレーショナルコードで解決するのが困難であった多くの問題があります。たとえば、「最大同時ログイン」問題を考えてみてください。ログインまたはログアウトを示す記録と時間があるので、一度にログインしたユーザーの最大数はそうでした。最も簡単な解決策は、レコードを反復処理し、ログイン/ログアウトが発生したときにカウンターを増分/減分し、この値の最大値を追跡することです。五月、わかりません)、あなたができる最善はCURSORです(純粋にリレーショナルなソリューションはすべて複雑さの異なる順序にあり、whileループを使用してそれを解決しようとするとパフォーマンスが低下します)。この場合、はい、C#ソリューションはT-SQLで達成できる期間よりも実際に高速です。それは大げさなように思えるかもしれませんが、この問題は、相対的な変化を表す行を操作していて、それらのウィンドウ集計を計算する必要がある場合、金融システムで簡単に現れます。ストアドプロシージャの呼び出しも高価になる傾向があります-些細なSPを100万回呼び出し、C#関数の呼び出しと比較してください。私は上記の他のいくつかの例をほのめかしました-T-SQLで適切なハッシュテーブル(実際にはいくつかの利点を提供するもの)を実装している人はまだいませんが、C#では非常に簡単です。繰り返しになりますが、DBが優れている点と、それほど優れていない点があります。C#でJOIN、SUM、およびGROUP BYを行いたくないのと同じように、T-SQLで特にCPUを集中的に使用するものは書きたくありません。