亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

練習 MongoDB 操作 —— 索引篇(二)

luqiuwen / 3217人閱讀

摘要:所以,如果你很少對集合進行讀取操作,建議不使用索引內(nèi)存使用由于索引是存儲在內(nèi)存中你應該確保該索引的大小不超過內(nèi)存的限制。如果索引的大小大于內(nèi)存的限制,會刪除一些索引,這將導致性能下降。

本文圍繞索引、游標兩部分進行探索,對MongoDB數(shù)據(jù)庫的索引部分有一個大概的了解;

索引

索引通常能夠極大的提高查詢的效率,如果沒有索引,MongoDB在讀取數(shù)據(jù)時必須掃描集合中的每個文件并選取那些符合查詢條件的記錄。這種掃描全集合的查詢效率是非常低的,特別在處理大量的數(shù)據(jù)時,查詢可以要花費幾十秒甚至幾分鐘,這對網(wǎng)站的性能是非常致命的。

索引是特殊的數(shù)據(jù)結構,索引存儲在一個易于遍歷讀取的數(shù)據(jù)集合中,索引是對數(shù)據(jù)庫表中一列或多列的值進行排序的一種結構。索引,從創(chuàng)建的形式上可以分為普通索引復合索引、數(shù)組索引、子文檔索引;

應該了解的索引限制,

開銷:每個索引占據(jù)一定的存儲空間,在進行插入,更新和刪除操作時也需要對索引進行操作。所以,如果你很少對集合進行讀取操作,建議不使用索引;

內(nèi)存(RAM)使用:由于索引是存儲在內(nèi)存中,你應該確保該索引的大小不超過內(nèi)存的限制。如果索引的大小大于內(nèi)存的限制,MongoDB會刪除一些索引,這將導致性能下降。

最大范圍:

(1)集合中索引不能超過 64 個;
(2)索引名的長度不能超過 125 個字符;
(3)一個復合索引最多可以有 31 個字段

索引不能被以下的查詢使用;可以調(diào)用explain()方法查看是否使用索引;

(1)正則表達式及非操作符,如 `$nin`, `$not`, 等
(2)算術運算符,如 `$mod` 等
(3)`$where` 子句

操作 創(chuàng)建索引

為集合grade_1_4根據(jù)性別和年齡創(chuàng)建復合索引:

db.getCollection("grade_1_4").ensureIndex({"sex": 1, "age": 1})

會得到結果:

{
    "v" : 2,                  // 索引的版本號。默認的索引版本取決于mongod創(chuàng)建索引時運行的版本
    "key" : {
        "sex" : 1,
        "age" : 1
    },
    "name" : "sex_1_age_1",
    "ns" : "school.grade_1_4"
}

說明:基于sexage的查詢將會用到該復合索引,或者是基于sex的查詢也會用到該索引,但是只是基于age的查詢將不會用到該復合索引。因此可以說,如果想用到復合索引,必須在查詢條件中包含復合索引中的前N個索引列。然而如果查詢條件中的鍵值順序和復合索引中的創(chuàng)建順序不一致的話,MongoDB可以智能的幫助我們調(diào)整該順序,以便使復合索引可以為查詢所用

如果分別為性別和年齡創(chuàng)建索引:

db.getCollection("grade_1_4").ensureIndex({"sex": 1})
db.getCollection("grade_1_4").ensureIndex({"age": 1})

會得到這樣的結果:

{
    "v" : 2,
    "key" : {
        "sex" : 1
    },
    "name" : "sex_1",
    "ns" : "school.grade_1_4"
},
{
    "v" : 2,
    "key" : {
        "age" : 1
    },
    "name" : "age_1",
    "ns" : "school.grade_1_4"
}
查看索引

查看集合grade_1_4已經(jīng)創(chuàng)建的索引規(guī)則:

db.getCollection("grade_1_4").getIndexes()

查看集合grade_1_4索引占用內(nèi)存空間的大小,單位是字節(jié):

db.getCollection("grade_1_4").totalIndexSize()
刪除索引

刪除集合grade_1_4namesex_1的索引規(guī)則:

db.getCollection("grade_1_4").dropIndex({"sex": 1})
唯一索引

創(chuàng)建唯一索引與普通索引的區(qū)別在于,多一個可選參數(shù) unique;舉個例子,根據(jù)姓名創(chuàng)建唯一索引:

db.getCollection("grade_1_4").ensureIndex({"name":1}, {"unique":true})

創(chuàng)建唯一索引能夠保證每條記錄的name字段值是不重復的;

當一個文檔以唯一索引的方式保存到集合中去的時候,任何缺失的索引字段都會以null值代替,因此,不能在唯一索引上同時插入兩條缺省的記錄。

假設集合已經(jīng)存在一些記錄,在些基礎上創(chuàng)建唯一索引;此時,對這些已經(jīng)存在的記錄,如果索引項值是存在重復的,則創(chuàng)建索引時會報錯;如果一定要在這樣的鍵上創(chuàng)建唯一索引,那么系統(tǒng)將保存第一條記錄,剩下的記錄會被刪除,結合dropDups參數(shù)使用(此參數(shù)只能在mongodb 3.0版本之前使用):

db.getCollection("grade_1_4").ensureIndex({"name":1}, {unique:true, dropDups: true})
稀疏索引

稀疏索引的創(chuàng)建和完全索引的創(chuàng)建沒有什么不同。使用稀疏索引進行查詢的時候,某些由于缺失了字段的文檔記錄可能不會被返回,這是由于稀疏索引子返回被索引了的字段。

示例:

> db.people.ensureIndex({title:1},{sparse:true}) //在title字段上建立稀疏索引
> db.people.save({name:"Jim"})
> db.people.save({name:"yang",title:"prince"})
> db.people.find();
{ "_id" : ObjectId("4e244dc5cac1e3490b9033d7"), "name" : "Jim" }
{ "_id" : ObjectId("4e244debcac1e3490b9033d8"), "name" : "yang", "title" : "prince" }

> db.people.find().sort({title:1})//自有包含有索引字段的記錄才被返回
{ "_id" : ObjectId("4e244debcac1e3490b9033d8"), "name" : "yang", "title" : "prince" }

> db.people.dropIndex({title:1})//刪除稀疏索引之后,所有的記錄均顯示
{ "nIndexesWas" : 2, "ok" : 1 }

> db.people.find().sort({title:1})
{ "_id" : ObjectId("4e244dc5cac1e3490b9033d7"), "name" : "Jim" }
{ "_id" : ObjectId("4e244debcac1e3490b9033d8"), "name" : "yang", "title" : "prince" }
性能示例

創(chuàng)建三十萬條數(shù)據(jù)

for (var i = 1; i <= 300000; i++) {
    db.getCollection("grade_1_5").insert({
       "name": "zhangsan" + i,
       "sex": Math.round(Math.random() * 10) % 2,
       "age": Math.round(Math.random() * 6) + 3
   });
}

根據(jù)姓名查一些特定的人

db.getCollection("grade_1_5").find(
    {
        $or: [{"name":"zhangsan10000"},{"name":"zhangsan14000"},{"name":"zhangsan9000"},{"name":"zhangsan23000"},{"name":"zhangsan24050"},
              {"name":"zhangsan12000"},{"name":"zhangsan14300"},{"name":"zhangsan9300"},{"name":"zhangsan23300"},{"name":"zhangsan24350"},
              {"name":"zhangsan11100"},{"name":"zhangsan15200"},{"name":"zhangsan8100"},{"name":"zhangsan22100"},{"name":"zhangsan26150"},
              {"name":"zhangsan10200"},{"name":"zhangsan14020"},{"name":"zhangsan9020"},{"name":"zhangsan23020"},{"name":"zhangsan24070"},
              {"name":"zhangsan10300"},{"name":"zhangsan14030"},{"name":"zhangsan9030"},{"name":"zhangsan23030"},{"name":"zhangsan24080"}]
    }
)

對姓名建立索引,會占用5873664字節(jié)

db.getCollection("grade_1_5").ensureIndex({"name": 1})

對于上面的命令,通過調(diào)整順序,觀察時間,對性能有一些大概的了解;

行為 創(chuàng)建-查詢-建索引 創(chuàng)建-建索引-查詢 建索引-創(chuàng)建-查詢
創(chuàng)建時間 150.957s 150.957s 159.967s
查詢時間 1.024s 0.005s 0.005s
建立索引時間 0.527s 0.527s 0.009s
游標

直接對一個集合調(diào)用find()方法時,我們會發(fā)現(xiàn),如果查詢結果超過二十條,只會返回二十條的結果,這是因為Mongodb會自動遞歸find()返回的是游標。

var cursor = db.getCollection("grade_1_4").find({});

執(zhí)行上述命令時,shell并不會真正地訪問數(shù)據(jù)庫,而是等待開始要求獲得結果的時候才向數(shù)據(jù)庫發(fā)送查詢請求。

此時可以對這個游標進行各種設置,然后調(diào)用游標的hashNext()next()方法,這樣就會真正訪問數(shù)據(jù)庫,這是一個懶加載的過程,如下

var cursor = db.getCollection("grade_1_4").find({});

while(cursor.hasNext()){  
    var doc = cursor.next();  
    // do stuff with doc  
};  

可以基于游標,進行limit、skip、sort操作,一般應用于分頁場景;

limit:限制游標返回的數(shù)量,指定了上限;

skip :忽略前面的部分文檔,如果文檔總數(shù)量小于忽略的數(shù)量,則返回空集合;

sort :對得到的子集合進行排序,可以按照多個鍵進行正反排序;

上述三個命令可以進行鏈式操作;

附錄

以下是文章會用到的參考,及有意義的擴展閱讀;

DrifterJ"s Stash的博客 - 學習MongoDB--(4-3):MongoDB查詢(游標使用)

MongoDB使用小結:一些不常見的經(jīng)驗分享

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/19109.html

相關文章

  • mysql - 收藏集 - 掘金

    摘要:步優(yōu)化以及其它數(shù)據(jù)庫后端掘金原文鏈接在發(fā)表了一篇簡潔有效有趣和令人信服的分鐘教程描述了如何進行優(yōu)化。關于的七種后端掘金對于的,在學習起來可能是比較亂的。 5 步優(yōu)化 MongoDB 以及其它數(shù)據(jù)庫 - 后端 - 掘金原文鏈接 Jared Rosoff 在 Scale Out Camp 發(fā)表了一篇簡潔、有效、有趣和令人信服的《8 分鐘 MongoDB 教程》描述了如何進行 MongoDB...

    Donald 評論0 收藏0
  • 練習 MongoDB 操作 —— 數(shù)據(jù)操作(一)

    摘要:本文的目標是通過大量的示例,來更好的理解如果在中進行數(shù)據(jù)操作初入客戶端剛利用命令進入客戶端環(huán)境,此時對數(shù)據(jù)庫一無所知舉目四望,想知道現(xiàn)在有哪些數(shù)據(jù)庫,因為是新裝的環(huán)境,所以只看到了和兩個默認就存在的數(shù)據(jù)庫目光慢慢收回,那么當前是處于哪個數(shù)據(jù) 本文的目標是通過大量的示例,來更好的理解如果在Mongodb中進行數(shù)據(jù)操作; 初入客戶端剛利用 mongod命令進入客戶端環(huán)境,此時對數(shù)據(jù)庫一無所...

    printempw 評論0 收藏0
  • MongoDB教程合集

    摘要:磕磕絆絆,我們的系列教程終于落下帷幕,從月第一篇開始到現(xiàn)在,中間有一段時間開小差,不過還好沒有爛尾。好了,這里我再把本系列的所有文章羅列出來,以供小伙伴們搜索查看。 磕磕絆絆,我們的MongoDB系列教程終于落下帷幕,從11月21第一篇開始到現(xiàn)在,中間有一段時間開小差,不過還好沒有爛尾。好了,這里我再把本系列的所有文章羅列出來,以供小伙伴們搜索查看。 1.Linux上安裝Mongo...

    FingerLiu 評論0 收藏0
  • 手把手教你 MongoDB 的安裝與詳細使用(

    摘要:實例教程是一個數(shù)據(jù)庫搜云庫教程專注于開發(fā)技術的研究與知識分享方法中你也可以設置使用多個字段創(chuàng)建索引關系型數(shù)據(jù)庫中稱作復合索引。 上一篇文章練習了,MongoDB 的以下操作 安裝 MongoDB 服務 連接 MongoDB MongoDB 創(chuàng)建數(shù)據(jù)庫 MongoDB 刪除數(shù)據(jù)庫 MongoDB 插入文檔 MongoDB 刪除文檔 MongoDB 查詢文檔 MongoDB AND 條件...

    jayzou 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<