SQLer 生島勘富 のブログ

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

NoSQL と SQL について

かなり古いネタですが、DeNA の松信氏のブログから NoSQL と SQLについて考えてみましょう。

目次

 

 

DeNA の松信氏のブログ

元記事はこちら。

yoshinorimatsunobu.blogspot.com

日本語訳はこちら。

www.publickey1.jp

DeNA の松信氏がやった実験

以下のような SQL

"select user_name,..
from test.user where user_id=?"

 1Gbps の NIC を 4枚挿ししたサーバに対し1千万回投げて、1秒間に処理できた件数を測ったというもの。

結果は以下のようになっています。

f:id:Sikushima:20190419185229p:plain


意外に思う人が多いとは思いますが、SQL が一番 CPU の利用率が低いです。これは私たち DB屋さんの「CPUを使い切る方が難しいよね」という感覚が実験結果でも再現されていると言えます。CPUを使い切るとしたら、よっぽど下手くそな SQL を書くか、GIS など内部的な計算が異常に多くなる処理をしなければ 100%に張り付くなんてことは起きないのです。

一番遅いのはネットワーク

全てのデータがメモリ上にキャッシュされている(松信氏の実験)ことを前提とすると、一番遅いのはネットワークで、この実験の場合、理論値でも1Gbpsしか出ていません。

他の条件として、memcached も、SQLを使わないでデータにアクセスしていますが、Handler Socket は、MySQLAPI を利用して SQL を使わないでデータにアクセスしています。つまり、データにアクセスする部分については、SQLを使ったときと同じなのです。

そこから、結果をイメージ化すると図のようになります。

f:id:Sikushima:20190419190018p:plain

松信氏のブログから、リクエスト、レスポンスもネットワークの負荷が小さくなるように工夫したと書いてあるので、そのようにして、4倍差、7倍差をつけてみました。

memcashed のデータ処理の速度が MySQL と同じではないでしょうが、大差はないと仮定して作っています。いずれにしても、SQLのオーバーヘッドと、ネットワークの処理時間が大きくなければ、4倍(memcashed)7倍(Handler Socket)という速度差は成り立ちません。

SQLは滅茶苦茶重いが、速くもできる!

RDBSQL の概念)が発表されたのは1969年。50年前です。

ネットワークは今とは桁違いに遅い

端末に処理能力がない

という条件のもとに考え出された概念ですから、サーバで一括処理して端末に結果だけを送る。という前提で作られています。

つまり、

"select user_name,..
from test.user where user_id=?" 

というような SQL を「1千万回も送る」というような処理は、そもそも想定されていないのです。

それぞれを限界までチューニングするという風にして条件をそろえるなら、

"select user_name,..
from test.user where user_id between 1 AND 2500000" 

という SQL × 4(ポートの数)と、memcached や、Handler Socket を比べることになるでしょう。そうすれば100% SQLの方が速いと断言できます。

処理にもよりますが、数回~数十回の NoSQL の処理を、1回の SQL にまとめることができた時点で逆転します。

 f:id:Sikushima:20190419190303p:plain

ユーザアクションに対して SQL は極力1回にする

つまり、ユーザアクションに対して SQL の発行は極力1回に抑えるべきです。

ですから、「1回のユーザアクションに対して、1件のレコードしか処理しない」という要件のときには、RDBMS を使うべきではありません。

「1回のユーザアクションに対して、1件のレコードしか処理しない」というようなことが比較的多いシステム(例えばゲーム)のときは、Handler Socket や、NoSQL API のようなものを使い、複数のレコードを処理できるときは SQL を使うという併用が良いでしょう。

まとめ - NoSQL を使うべきとき

SQLRDBMS)は、もちろん完璧ではありませんから、何でもかんでも使えばよいということではありません。NoSQLを選択すべきときは以下のようなシステムのときになります。

  • 極端に否定形のデータを扱う(ドキュメント型)
  • レコード単位の処理がない(列指向)
  • レコード単位の処理しかない(KVS)

レコード単位の処理も、複数のレコード単位の処理もある。というときは、Handler Socket や、NoSQL API のような SQL の解析をスキップできるものと、SQLの併用。

 

レコード単位の処理が少ないときは、SQL になるでしょう。