日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mongo中的游标与数据一致性的取舍

發布時間:2025/5/22 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mongo中的游标与数据一致性的取舍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

除了特殊注釋外,本文的測試結果均基于?spring-data-mongodb:1.10.6.RELEASE(spring-boot-starter:1.5.6.RELEASE),MongoDB 3.0.6


  我們在學習了一門編程語言時,一定要明白語句底層的意義,比如 User user= new User(); 它在堆中開辟了一個空間用于存放User(),并且在棧中新增了一個指向這個堆空間的指針user。那么,mongo shell中的 var user = db.user.find(); 到底做了什么?也是為集合user開辟了一個堆空間,然后再讓user指向這個空間嗎?

?  讓我們先來做個實驗

> function testTime(){ ... var date1 = new Date().getTime(); ... for(var i = 0; i < 10000; i++){ ... var user = db.user.find(); ... } ... return new Date().getTime() - date1; ... } > testTime(); 165

  user表中是有100w條數據的,100萬條數據的空間創建10000次,只用了165ms?

  顯然是不現實的,我們再看一下

> function testTime(){ var date1 = new Date().getTime();for(var i = 0; i < 100; i++){ var user = db.user.aggregate(); }return new Date().getTime() - date1; } > testTime(); 2800

  這里我們將find方法替換成了aggregate,并且將10000次循環改成了100次,然后時間卻上升了到2800ms。通過第二章我們知道aggregate的底層是findOne,讓我們再回頭仔細看看findOne和find的代碼區別

> db.user.find function ( query , fields , limit , skip, batchSize, options ){var cursor = new DBQuery( this._mongo , this._db , this ,this._fullName , this._massageObject( query ) , fields ,limit , skip , batchSize , options || this.getQueryOptions() );var connObj = this.getMongo();var readPrefMode = connObj.getReadPrefMode();if (readPrefMode != null) {cursor.readPref(readPrefMode, connObj.getReadPrefTagSet());}return cursor; //find方法返回的是一個游標 } > db.user.findOne function ( query , fields, options ){var cursor = this.find(query, fields, -1 /* limit */, 0 /* skip*/,0 /* batchSize */, options);if ( ! cursor.hasNext() )return null;var ret = cursor.next();if ( cursor.hasNext() ) throw Error( "findOne has more than 1 result!" );if ( ret.$err )throw Error( "error " + tojson( ret ) );return ret; //findOne返回的是具體的數據 }

  另外,spring-data-mongodb中的其實也有這么一對相對的方法

?

  平均90%的CPU占有率跑了70分鐘,說明??mongoTemplate.getCollection("user").find(new BasicDBObject())?其實也沒有直接請求全部的數據,而是返回了一個類似于指針的游標。在? ?spring-data-mongodb:2.1.2RELEASE中已經去除掉這個方法,那么這個方法的優缺點是啥,為什么要去掉這個方法呢?

  上面的各種測試結果表明了返回游標的好處(957ms 對上 4420270ms)。當然t它也卻在很致命的缺點:查詢過程中若文檔變大,可能因為空間位置不足,而移動到集合的末尾,這樣這個位置變動的文檔就可能會被讀取到兩次,造成數據的誤差。性能的提升固然重要,但是正確性才是數據庫的核心,這可能就是新版本的spring-data-mongodb去掉了直接獲取游標的方法的原因吧。

  在mongo shell中提供了專門的快照功能,用于避免游標可能造成的數據重復問題,使用方式:db._collection_.find().snapshot();

  因為游標是為了避免一次去除過多數據造成性能的浪費,所以它對一些情況是不適用的。比如

  (1) findOne,只取一條數據,那么也就不需要返回游標了

  (2) 數據庫操作命令,用戶只關注的是操作成功或失敗

  (3) 分組函數,這些函數需要遍歷完所有的數據,才能得出最后的結果

  因此,便有了最開始的runCommand調用了findOne方法,而為了與一般的數據查詢的區分,mongo就提供了一個特殊集合$cmd用于執行(2)、(3)情況的函數。這個$cmd集合無法插入數據,無法直接查詢數據,使用db.getCollectionNames();時也不會展示,只有使用相應的操作符的時候,可以進行相應的查詢。

  在新版本中,$cmd藏的更深了,我一直糾結的雞生蛋蛋生雞的情況也不見了,我上面總結的一些情況也過時了。技術就是這樣,總是在不斷的過時,但是思維不會過時,邏輯不會過時,各位,共勉之。


?目錄

  一:spring-data-mongodb 使用原生aggregate語句

  二:mongo的runCommand與集合操作函數的關系

  三:spring-data-mongodb與mongo shell的對應關系

  四:mongo中的游標與數據一致性的取舍

轉載于:https://www.cnblogs.com/ttjsndx/p/9947911.html

總結

以上是生活随笔為你收集整理的mongo中的游标与数据一致性的取舍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。