ホームページ データベース mysql チュートリアル 研究了这么久的MongoDB,我也来吐下槽。

研究了这么久的MongoDB,我也来吐下槽。

Jun 07, 2016 pm 05:56 PM
mongodb 研究

MongoDB做为一款NOSQL数据库,在刚接触它的时候,被它的性能深深的吸引了。在一四核,4G内存的centos虚拟机上,插入了500W每条大小200byte的数据。发现它的写性能太令我震惊了。在不做索引的情况下,前一百万条,只用了二分钟就插完了,这只是我WIN7上的一台

   MongoDB做为一款NOSQL数据库,在刚接触它的时候,被它的性能深深的吸引了。在一四核,4G内存的centos虚拟机上,插入了500W每条大小200byte的数据。发现它的写性能太令我震惊了。在不做索引的情况下,前一百万条,只用了二分钟就插完了,这只是我WIN7上的一台虚拟机,WIN7执行插入操作。在先建索引的情况下,再插入了一百万条,只是比没有索引的情况下,慢了20秒。但发现它对磁盘的占用,有点超出了我的估计!它占用的磁盘空间太大,而实际上数据大小没有这么大。磁盘占用大小差不多是数据的三倍。

  插完数据后,进行了一些读取操作。性能还是非常可观的,查询都是MS秒级的。欣喜之余,接着再插数据。坑爹的事情就发生了。32位的mongodb最大一块文件块是512M,当512M有存储空间用完时,再插数据会先划出512M的数据块。当内存被大量占用后,发现它的插入数据,变龟速了。特别是在开辟一块新的存储空间时,完全阻塞了。Mongo在内存足够的情况下,开始插入的数据能达到6000条/秒,到内存不足后,速度瞬间降到了200条/秒,如果内存进一步退化,索引比数据量大的话,香港空间,有可能完全阻塞。

  换到64位的MongoDB测试,发现他的内存充足的情况下,比32位的插入100W条速度要快到十几秒。而且64位的MongoDB,他最大的一块存储是2G的数据块。当内存不足的情况下,哥哭了~~~,绝大部分时间在阻塞。速度降到你不能忍受。关闭MongoDB,重启centos后,再接着插入,在将部分MongoDB的数据加载进内存后,又非常快了,插入速度几M/秒。好景不长,当2G的数据块用完后,再开辟一块2G的数据块时,发现MongoDB占用的内存瞬间升高,写入速度直线下降,直至阻塞。我怀疑MongoDB在开辟了那2G的空间后,同时在内存中开辟了一块2G的内存,由于当时内存不足(发现SWAP中的虚拟内存也占用过高),所以产生了阻塞情况。MongoDB可能是内存映射写入方式,所以它在内存足够的情况下,写入速度非常快。建议实际生产环境中,如果数据量大的话,给它多留点内存吧,MongoDB绝对是吃内存的老虎。

  之后重启centos,内存又降下来了,MongoDB中已经存储了500万条数据了,再进行有索引查询,发现MongoDB在数据在冷的情况下,响应很慢,多执行几次查询预热后,性能才能回升,直至像刚插入时再查询那样。500万条数据查询,返回1000行数据内的,有索引情况下,查询时间是几十MS,然后继续测试了各种复杂查询。执行下面一条语句后,哥泪牛满面了

db.jqueue.find({"$or":[{"Name":"janson7"},{"Age":{"$in":[1,2,3]}}]}).sort({"_id":-1}).explain() { "cursor" : "BtreeCursor _Name_ reverse", "isMultiKey" : false, "n" : 301, "nscannedObjects" : 5000000, "nscanned" : 5000000, "nscannedObjectsAllPlans" : 5000000, "nscannedAllPlans" : 5000000, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 50989, "indexBounds" : { "_id" : [ [ { "$maxElement" : 1 }, { "$minElement" : 1 } ] ] }, "server" : "localhost:27017" }

  发现他全表遍历了一次,反复测试后,都是这样的情况,一去掉sort,后,就是直接读索引,或者把OR操作去掉,也是读索引。我认为,排序应该是在查询到的数据中进行排序的,也就是先去索引中找到了相应的项,再把项根据我的要求排序啊,不可能出现遍历表的情况。

  然后经过了坚辛的百度和Google,终于找到了答案,原来这是MongoDB的一个Bug,从他一设计出来后,这个Bug就一直没解决过。

  园子里这位兄台的文章里写了

  它自已的官方上的反馈:https://jira.mongodb.org/browse/SERVER-1205 发现这个问题,从10年就有人提出了,直到现在,2.2.2版本了,都还没有解决。如果有要进行$or查询,再sort排序业务的兄弟,请三思,我们开始想用MongoDB,就是因为我们业务里面这个查询是一个非常频繁且关键的查询。

  在倍受打击后,改变设计方法,改变业务模式,虚拟主机,我不再进行$or查询了,我直接用Capped Collection来做一个临时映射,通过Capped表中数据进行排序,分页偏移,再用ID去主表查询。

  在使用Capped Collection时,又发现了坑爹的事。2.2之前的版本,Capped Collection是默认没有索引的,2.2后就默认加了_id,并做索引了.我用的是C#驱动,然后按照驱动说明方法,

var collectionOptions = CollectionOptions.SetCapped(true).SetMaxDocuments(1000).SetMaxSize(1000000).SetAutoIndexId(false);

  建了一个Capped表,去MongoDB里面看,发现,他还是建了索引。头大了,又开始找资料,发现了官方提供的驱动版本是1.7版本以前的,网站空间,也就是说,这个版本有可能不会支持2.2的新功能,在2.2以前,Capped默认是不建索引的,2.2是默认建索引了。查找官方驱动源码,下载地址:https://github.com/mongodb/mongo-csharp-driver

 

Sets whether the collection is capped. CollectionOptionsBuilder SetCapped(bool value) { if (value) { _document[] = value; } else { _document.Remove(); } return this; }

发现他的源码是这样写的,因为早期版本默认情况下是不建索引的,所以,如果 SetCapped传入的参数是false的话,他就直接执行了_document.Remove("capped");这一句,直接把这个参数选项从CollectionOptions项中删除了,没有带这个参数传入至数据库,而默认情况下,它是要建索引的,也就是说,在这个驱动版本,你是怎么样做Capped都会给你建索引,最后没办法,只好改了他的源码

 

Sets whether the collection is capped. CollectionOptionsBuilder SetCapped(bool value) { _document.Remove(); }

让它不管输入什么参数,这项都得输入,然后再执行时 ,发现MongoDB里面的Capped就没有建索引了。

  

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

作曲家を使用して、推奨システムのジレンマを解決する:Andres-Montanez/推奨 作曲家を使用して、推奨システムのジレンマを解決する:Andres-Montanez/推奨 Apr 18, 2025 am 11:48 AM

eコマースのWebサイトを開発するとき、私は困難な問題に遭遇しました。ユーザーにパーソナライズされた製品の推奨事項を提供する方法です。当初、私はいくつかの簡単な推奨アルゴリズムを試しましたが、結果は理想的ではなく、ユーザーの満足度も影響を受けました。推奨システムの精度と効率を改善するために、より専門的なソリューションを採用することにしました。最後に、Andres-Montanez/Adcumentations Bundleを介してAndres-Montanez/Bundleをインストールしました。これは、問題を解決しただけでなく、推奨システムのパフォーマンスを大幅に改善しました。次の住所から作曲家を学ぶことができます。

MongoDBデータベースパスワードを表示するNAVICATの方法 MongoDBデータベースパスワードを表示するNAVICATの方法 Apr 08, 2025 pm 09:39 PM

Hash値として保存されているため、Navicatを介してMongoDBパスワードを直接表示することは不可能です。紛失したパスワードを取得する方法:1。パスワードのリセット。 2。構成ファイルを確認します(ハッシュ値が含まれる場合があります)。 3.コードを確認します(パスワードをハードコードできます)。

CentosでGitLabのデータベースを選択する方法 CentosでGitLabのデータベースを選択する方法 Apr 14, 2025 pm 04:48 PM

gitlabデータベース展開ガイドcentosシステム適切なデータベースの選択は、gitlabを正常に展開するための重要なステップです。 GitLabは、MySQL、PostgreSQL、MongoDBなど、さまざまなデータベースと互換性があります。この記事では、これらのデータベースを選択して構成する方法を詳細に説明します。データベース選択の推奨MYSQL:広く使用されているリレーショナルデータベース管理システム(RDBMS)。安定したパフォーマンスを備えており、ほとんどのGitLab展開シナリオに適しています。 POSTGRESQL:強力なオープンソースRDBMSは、大規模なデータセットの処理に適した複雑なクエリと高度な機能をサポートしています。 Mongodb:人気のNoSQLデータベース、海の扱いが上手です

Centos Mongodbバックアップ戦略とは何ですか? Centos Mongodbバックアップ戦略とは何ですか? Apr 14, 2025 pm 04:51 PM

MongoDB効率的なバックアップ戦略の詳細な説明CENTOSシステムでは、この記事では、データセキュリティとビジネスの継続性を確保するために、CENTOSシステムにMongoDBバックアップを実装するためのさまざまな戦略を詳細に紹介します。 Dockerコンテナ環境でのマニュアルバックアップ、タイミング付きバックアップ、自動スクリプトバックアップ、バックアップメソッドをカバーし、バックアップファイル管理のベストプラクティスを提供します。マニュアルバックアップ:MongoDumpコマンドを使用して、マニュアルフルバックアップを実行します。たとえば、Mongodump-Hlocalhost:27017-U Username-P Password-Dデータベース名-O/バックアップディレクトリこのコマンドは、指定されたデータベースのデータとメタデータを指定されたバックアップディレクトリにエクスポートします。

MongoDBおよびリレーショナルデータベース:包括的な比較 MongoDBおよびリレーショナルデータベース:包括的な比較 Apr 08, 2025 pm 06:30 PM

MongoDBおよびリレーショナルデータベース:詳細な比較この記事では、NOSQLデータベースMongoDBと従来のリレーショナルデータベース(MySQLやSQLServerなど)の違いを詳細に調べます。リレーショナルデータベースは、行と列のテーブル構造を使用してデータを整理しますが、MongoDBは柔軟なドキュメント指向モデルを使用して、最新のアプリケーションのニーズをより適切に適しています。主にデータ構造を区別します。リレーショナルデータベースは、事前定義されたスキーマテーブルを使用してデータを保存し、テーブル間の関係は一次キーと外部キーを通じて確立されます。 MongoDBはJSONのようなBSONドキュメントを使用してコレクションに保存します。各ドキュメント構造は、パターンのないデザインを実現するために独立して変更できます。アーキテクチャデザイン:リレーショナルデータベースは、事前に定義された固定スキーマが必要です。 Mongodbサポート

Mongodbでユーザーをセットアップする方法 Mongodbでユーザーをセットアップする方法 Apr 12, 2025 am 08:51 AM

MongoDBユーザーを設定するには、次の手順に従ってください。1。サーバーに接続し、管理者ユーザーを作成します。 2。ユーザーアクセスを許可するデータベースを作成します。 3. CreateUserコマンドを使用してユーザーを作成し、その役割とデータベースアクセス権を指定します。 4. Getusersコマンドを使用して、作成されたユーザーを確認します。 5.オプションで、特定のコレクションに他のアクセス許可または付与ユーザーの権限を設定します。

Debian Mongodbでデータを暗号化する方法 Debian Mongodbでデータを暗号化する方法 Apr 12, 2025 pm 08:03 PM

DebianシステムでMongoDBデータベースを暗号化するには、次の手順に従う必要があります。ステップ1:MongoDBのインストール最初に、DebianシステムがMongoDBをインストールしていることを確認してください。そうでない場合は、インストールについては公式のMongoDBドキュメントを参照してください:https://docs.mongodb.com/manual/tutorial/install-mongodb-onedbian/-step 2:暗号化キーファイルを作成し、暗号化キーを含むファイルを作成し、正しい許可を設定します。

Mongodbに接続するためのツールは何ですか Mongodbに接続するためのツールは何ですか Apr 12, 2025 am 06:51 AM

Mongodbに接続するための主なツールは次のとおりです。1。Mongodbシェル、迅速な表示と簡単な操作の実行に適しています。 2。プログラミング言語ドライバー(Pymongo、Mongodb Javaドライバー、Mongodb node.jsドライバーなど)、アプリケーション開発に適していますが、使用方法をマスターする必要があります。 3。GUIツール(Robo 3T、Compassなど)は、初心者と迅速なデータ表示のためのグラフィカルインターフェイスを提供します。ツールを選択するときは、アプリケーションのシナリオとテクノロジースタックを検討し、接続プールやインデックスの使用などの接続文字列の構成、許可管理、パフォーマンスの最適化に注意する必要があります。

See all articles