MongoDBは魔法のように高速ではありません。同じデータを保存し、基本的に同じ方法で整理し、まったく同じ方法でアクセスする場合、結果が大きく異なることを期待するべきではありません。結局のところ、MySQLとMongoDBはどちらもGPLであるため、Mongoに魔法のように優れたIOコードが含まれている場合、MySQLチームはそれをコードベースに組み込むことができます。
人々は実際のMongoDBのパフォーマンスを目にしています。これは主に、MongoDBを使用すると、ワークロードにより適した別の方法でクエリを実行できるためです。
たとえば、複雑なエンティティに関する多くの情報を正規化された方法で永続化した設計について考えてみます。これにより、MySQL(または任意のリレーショナルデータベース)の数十のテーブルを簡単に使用して、データを通常の形式で格納できます。テーブル間のリレーショナル整合性を確保するには、多くのインデックスが必要です。
ここで、ドキュメントストアと同じデザインを検討します。これらの関連するすべてのテーブルがメインテーブルに従属している場合(多くの場合、従属している場合)、エンティティ全体が単一のドキュメントに格納されるようにデータをモデル化できる場合があります。 MongoDBでは、これを1つのドキュメントとして1つのコレクションに保存できます。ここから、MongoDBが優れたパフォーマンスを実現し始めます。
MongoDBでは、エンティティ全体を取得するには、次の手順を実行する必要があります。
- コレクションに対する1つのインデックスルックアップ(エンティティがidによってフェッチされると想定)
- 1つのデータベースページ(実際のバイナリjsonドキュメント)のコンテンツを取得します
したがって、bツリールックアップとバイナリページの読み取り。 Log(n)+1IO。インデックスが完全にメモリに存在できる場合は、1IO。
20個のテーブルがあるMySQLでは、次のことを実行する必要があります。
- ルートテーブルでの1つのインデックスルックアップ(ここでも、エンティティがidによってフェッチされていると仮定します)
- クラスター化されたインデックスを使用すると、ルート行の値がインデックスに含まれていると見なすことができます
- エンティティのpk値の20以上の範囲ルックアップ(できればインデックス上)
- これらはおそらくクラスター化インデックスではないため、適切な子行が何であるかを把握したら、同じ20以上のデータルックアップを行います。
したがって、mysqlの合計は、すべてのインデックスがメモリ内にあると仮定しても(20倍多いため、より困難です)、約20の範囲ルックアップになります。
これらの範囲ルックアップはランダムIOで構成されている可能性があります。異なるテーブルはディスク上の異なる場所に確実に存在し、エンティティの同じテーブル内の同じ範囲内の異なる行が連続していない可能性があります(エンティティの状態によって異なります)更新など)
したがって、この例では、最終的な集計は約20回です。 MongoDBと比較して、論理アクセスあたりのMySQLでのIOが多くなります。
これが、MongoDBが一部のユースケースでパフォーマンスを向上させる方法です。 。