<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        關(guān)于mongodb創(chuàng)建索引的一些經(jīng)驗總結(jié)

        來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-09 15:02:09
        文檔

        關(guān)于mongodb創(chuàng)建索引的一些經(jīng)驗總結(jié)

        關(guān)于mongodb創(chuàng)建索引的一些經(jīng)驗總結(jié):想來接觸mongodb已經(jīng)快一年了,對于它的索引知識也積攢了不少經(jīng)驗,趁著這個月黑風(fēng)高的夜晚,就把mongodb的索引總結(jié)一番吧。 一,索引介紹 mongodb具有兩類索引,分別為單鍵索引和復(fù)合索引。 1.單鍵索引是最簡單的一種索引,創(chuàng)建單鍵索引的開銷要比復(fù)合索引
        推薦度:
        導(dǎo)讀關(guān)于mongodb創(chuàng)建索引的一些經(jīng)驗總結(jié):想來接觸mongodb已經(jīng)快一年了,對于它的索引知識也積攢了不少經(jīng)驗,趁著這個月黑風(fēng)高的夜晚,就把mongodb的索引總結(jié)一番吧。 一,索引介紹 mongodb具有兩類索引,分別為單鍵索引和復(fù)合索引。 1.單鍵索引是最簡單的一種索引,創(chuàng)建單鍵索引的開銷要比復(fù)合索引

        想來接觸mongodb已經(jīng)快一年了,對于它的索引知識也積攢了不少經(jīng)驗,趁著這個月黑風(fēng)高的夜晚,就把mongodb的索引總結(jié)一番吧。 一,索引介紹 mongodb具有兩類索引,分別為單鍵索引和復(fù)合索引。 1.單鍵索引是最簡單的一種索引,創(chuàng)建單鍵索引的開銷要比復(fù)合索引

        想來接觸mongodb已經(jīng)快一年了,對于它的索引知識也積攢了不少經(jīng)驗,趁著這個月黑風(fēng)高的夜晚,就把mongodb的索引總結(jié)一番吧。

        一,索引介紹


        mongodb具有兩類索引,分別為單鍵索引和復(fù)合索引。

        1.單鍵索引是最簡單的一種索引,創(chuàng)建單鍵索引的開銷要比復(fù)合索引小很多。單鍵索引主要用于針對單值查詢的條件。

        2.復(fù)合索引是將文檔中的幾個鍵聯(lián)合起來創(chuàng)建的一種索引,創(chuàng)建這種索引需要更多的空間與性能開銷。分別體現(xiàn)在:

        1).在給大量數(shù)據(jù)創(chuàng)建復(fù)合索引時,會阻塞數(shù)據(jù)庫的查詢,更不用說修改和插入操作了;

        2).插入一條數(shù)據(jù)時,要花費更多的時間來給復(fù)合索引加數(shù)據(jù);

        3).創(chuàng)建的復(fù)合索引所站得空間大小根據(jù)數(shù)據(jù)的類型以及鍵的數(shù)量而有所不同。比如,如果你用五個NumberInt的鍵創(chuàng)建的復(fù)合索引的空間大小,并不會比兩個NumberInt和一個String類型創(chuàng)建的復(fù)合索引占用更多的空間。索引在設(shè)計數(shù)據(jù)類型時,盡量將數(shù)據(jù)類型設(shè)置為NumberInt類型,以及盡量少使用string類型的數(shù)據(jù)做索引;

        二,創(chuàng)建索引


        創(chuàng)建索引的語句很簡單。

        1.單鍵索引的創(chuàng)建:db.test.ensureIndex({name:1},{name:'index_name'})

        2.復(fù)合索引的創(chuàng)建:db.test.ensureIndex({name:1,age:1,sex:1},{name:'index_nas'})

        三,索引優(yōu)化


        索引的優(yōu)化是一個重頭戲,需要詳細的來解釋。我得測試數(shù)據(jù)插入了100萬條。字段分別為name,sex,type,time,id

        1.我們來看一個簡單的查詢:db.test.find({name:'name_1'}) 相信大家對這個查詢已經(jīng)很熟悉了,然后我們來看看這個語句的索引執(zhí)行計劃:

        {
        	"cursor" : "BasicCursor", 查詢語句所用到的索引,而BasicCursor代表沒有索引
        	"isMultiKey" : false, 是否為復(fù)合索引
        	"n" : 1, 查詢到的結(jié)果數(shù)
        	"nscannedObjects" : 1000000, 掃描的文檔數(shù)量
        	"nscanned" : 1000000, 掃面的索引數(shù)量
        	"nscannedObjectsAllPlans" : 1000000, //影響的所有的被掃描文檔的總數(shù)量
        	"nscannedAllPlans" : 1000000, //所有被掃描的索引的總數(shù)量
        	"scanAndOrder" : false, 是否排序
        	"indexOnly" : false,
        	"nYields" : 2,
        	"nChunkSkips" : 0,
        	"millis" : 342, 花費的時間
        	"indexBounds" : {
        	
        	},
        	"server" : "node1:27017"
        }

        從這個執(zhí)行計劃中可以看出,該條查詢語句查詢一條數(shù)據(jù)需要掃描整個表,這肯定扯淡了嘛,那這時候就該給這個字段創(chuàng)建索引了,創(chuàng)建一個單鍵索引

        db.test.ensureIndex({name:1},{name:'index_name'})

        創(chuàng)建完索引之后,再來查看看這條查詢語句的執(zhí)行計劃:

        {
        	"cursor" : "BtreeCursor index_name",
        	"isMultiKey" : false,
        	"n" : 1,
        	"nscannedObjects" : 1,
        	"nscanned" : 1,
        	"nscannedObjectsAllPlans" : 1,
        	"nscannedAllPlans" : 1,
        	"scanAndOrder" : false,
        	"indexOnly" : false,
        	"nYields" : 0,
        	"nChunkSkips" : 0,
        	"millis" : 0,
        	"indexBounds" : {
        	"name" : [
        	[
        	"name_1",
        	"name_1"
        	]
        	]
        	},
        	"server" : "node1:27017"
        }

        簡直是逆天啊,nscanned和nscannedObjects居然從100萬下降到1條,也就是查詢數(shù)據(jù)時,只掃描了一條就已經(jīng)找到,而且花費的時間是0秒,沒有創(chuàng)建索引時,居然是342毫秒,絕對索引威武啊。

        2.這時候我想通過type和sex來組合查詢某一條件的數(shù)據(jù): db.test.find({type:1,sex:0}) 看看這句的執(zhí)行計劃:

        {
        	"cursor" : "BasicCursor",
        	"isMultiKey" : false,
        	"n" : 55555,
        	"nscannedObjects" : 1000000,
        	"nscanned" : 1000000,
        	"nscannedObjectsAllPlans" : 1000000,
        	"nscannedAllPlans" : 1000000,
        	"scanAndOrder" : false,
        	"indexOnly" : false,
        	"nYields" : 0,
        	"nChunkSkips" : 0,
        	"millis" : 529,
        	"indexBounds" : {
        	
        	},
        	"server" : "node1:27017"
        }

        從這個計劃中可以看出,為了查找?guī)兹f條數(shù)據(jù),它也掃描了整個表,很顯然,該創(chuàng)建索引了:

        db.test.ensureIndex({type:1,sex:1},{name:'index_ts'})

        創(chuàng)建完索引之后,再來執(zhí)行查詢語句,看看執(zhí)行計劃:

        db.test.find({type:1,sex:0}).explain()
        {
        	"cursor" : "BtreeCursor index_ts",
        	"isMultiKey" : false,
        	"n" : 55555,
        	"nscannedObjects" : 55555,
        	"nscanned" : 55555,
        	"nscannedObjectsAllPlans" : 55555,
        	"nscannedAllPlans" : 55555,
        	"scanAndOrder" : false,
        	"indexOnly" : false,
        	"nYields" : 0,
        	"nChunkSkips" : 0,
        	"millis" : 112,
        	"indexBounds" : {
        	"type" : [
        	[
        	1,
        	1
        	]
        	],
        	"sex" : [
        	[
        	0,
        	0
        	]
        	]
        	},
        	"server" : "node1:27017"
        }

        很顯然,絕對是一個最佳索引,因為n=nscannedObjects=nscanned了,而且查詢時間從529毫秒下降到112毫秒了,這也是一個質(zhì)的飛躍,可以明顯的看到,它使用了剛剛創(chuàng)建的index_ts索引。

        現(xiàn)在我又有一個需求了,我想通過時間再來排序,好的,我們執(zhí)行查詢語句: db.test.find({type:1,sex:0}).sort({time:-1}) 我們來看看這個查詢語句的執(zhí)行計劃:

        {
        	"cursor" : "BtreeCursor index_ts",
        	"isMultiKey" : false,
        	"n" : 55555,
        	"nscannedObjects" : 1000000,
        	"nscanned" : 1000000,
        	"nscannedObjectsAllPlans" : 1000000,
        	"nscannedAllPlans" : 1000000,
        	"scanAndOrder" : true,
        	"indexOnly" : false,
        	"nYields" : 1,
        	"nChunkSkips" : 0,
        	"millis" : 695,
        	"indexBounds" : {
        	"type" : [
        	[
        	1,
        	1
        	]
        	],
        	"sex" : [
        	[
        	0,
        	0
        	]
        	]
        	},
        	"server" : "node1:27017"
        }

        看到?jīng)],這個查詢語句跟上一個創(chuàng)建索引之后的查詢出來的結(jié)果相差還是很大的,scanAndOrder和millis,時間花費了將近700毫秒,而且在查詢完畢之后還要排序,這也太不近人情了,就加了一個排序操作,怎么會讓它從白天鵝變成丑小鴨了呢?啊,關(guān)鍵參數(shù)就是scanAndOrder,意思就是在內(nèi)存中把結(jié)果排序了嘛,那好啊,既然你如此薄情,那我就建個復(fù)合索引來對抗: db.test.ensureIndex({type:1,sex:1,time:-1},{name:'index_tst'})

        {
        	"cursor" : "BtreeCursor index_tst",
        	"isMultiKey" : false,
        	"n" : 55555,
        	"nscannedObjects" : 55555,
        	"nscanned" : 55555,
        	"nscannedObjectsAllPlans" : 55555,
        	"nscannedAllPlans" : 55555,
        	"scanAndOrder" : false,
        	"indexOnly" : false,
        	"nYields" : 0,
        	"nChunkSkips" : 0,
        	"millis" : 126,
        	"indexBounds" : {
        	"type" : [
        	[
        	1,
        	1
        	]
        	],
        	"sex" : [
        	[
        	0,
        	0
        	]
        	],
        	"time" : [
        	[
        	{
        	"$maxElement" : 1
        	},
        	{
        	"$minElement" : 1
        	}
        	]
        	]
        	},
        	"server" : "node1:27017"
        }

        看到了嗎?各種參數(shù)又回到最佳狀態(tài)了。這時候可能有人會問了,為什么要把time放到索引的最后而不是其它位置呢?其實這在創(chuàng)建索引時是有要求的,即:

        1. 將等值索引放在最前面

        2. 盡量將排序字段放在范圍字段的前面

        3. $nin和$ne跟索引沒有關(guān)系

          接下來我們再給查詢語句加條件: db.test.find({type:1,sex:0,id:{$gt:1,$lt:500000}}) 執(zhí)行計劃如下:

          {
          	"cursor" : "BasicCursor",
          	"isMultiKey" : false,
          	"n" : 55555,
          	"nscannedObjects" : 1000000,
          	"nscanned" : 1000000,
          	"nscannedObjectsAllPlans" : 1000000,
          	"nscannedAllPlans" : 1000000,
          	"scanAndOrder" : false,
          	"indexOnly" : false,
          	"nYields" : 2,
          	"nChunkSkips" : 0,
          	"millis" : 553,
          	"indexBounds" : {
          	
          	},
          	"server" : "node1:27017"
          }

          可以看到,只返回兩萬多條數(shù)據(jù),但是卻掃描了整個表,這肯定是很蛋疼的事情嘛,索引走起:

          db.test.ensureIndex({type:1,sex:1,id:1},{name:'index_tis'})

          {
          	"cursor" : "BtreeCursor index_tis",
          	"isMultiKey" : false,
          	"n" : 55555,
          	"nscannedObjects" : 55555,
          	"nscanned" : 55555,
          	"nscannedObjectsAllPlans" : 55555,
          	"nscannedAllPlans" : 55555,
          	"scanAndOrder" : false,
          	"indexOnly" : false,
          	"nYields" : 1,
          	"nChunkSkips" : 0,
          	"millis" : 137,
          	"indexBounds" : {
          	"type" : [
          	[
          	1,
          	1
          	]
          	],
          	"sex" : [
          	[
          	0,
          	0
          	]
          	],
          	"id" : [
          	[
          	1,
          	1000000
          	]
          	]
          	},
          	"server" : "node1:27017"
          }

          很顯然,這是個非常不錯的組合索引,那為何不把id放在其它地方,偏偏放在最后面呢?因為在mongodb中,索引是從左到右執(zhí)行的,因此顯然要從左到右一次過濾最大數(shù)量的數(shù)據(jù)顯然type和sex的組合過濾數(shù)據(jù)量要比id高更多,因為id的忙查率要遠高于這兩個組合。

          接著再把按time排序加上,查詢:db.test.find({type:1,sex:1,id:{$gt:0,$lt:1000000}}).sort({time:-1}).explain()

          {
          	"cursor" : "BasicCursor",
          	"isMultiKey" : false,
          	"n" : 55556,
          	"nscannedObjects" : 1000000,
          	"nscanned" : 1000000,
          	"nscannedObjectsAllPlans" : 1000000,
          	"nscannedAllPlans" : 1000000,
          	"scanAndOrder" : true,
          	"indexOnly" : false,
          	"nYields" : 1,
          	"nChunkSkips" : 0,
          	"millis" : 725,
          	"indexBounds" : {
          	
          	},
          	"server" : "node1:27017"
          }

          可以看到,這個查詢語句也是極其慢的,而且還要再內(nèi)存中排序,所以肯定要創(chuàng)建索引了:

          db.test.ensureIndex({type:1,sex:1,id:1,time:-1},{name:'index_tist'}) 我們先這樣創(chuàng)建索引,看看執(zhí)行計劃:

          {
          	"cursor" : "BtreeCursor index_tist",
          	"isMultiKey" : false,
          	"n" : 55556,
          	"nscannedObjects" : 55556,
          	"nscanned" : 55556,
          	"nscannedObjectsAllPlans" : 55657,
          	"nscannedAllPlans" : 55657,
          	"scanAndOrder" : true,
          	"indexOnly" : false,
          	"nYields" : 0,
          	"nChunkSkips" : 0,
          	"millis" : 404,
          	"indexBounds" : {
          	"type" : [
          	[
          	1,
          	1
          	]
          	],
          	"sex" : [
          	[
          	1,
          	1
          	]
          	],
          	"id" : [
          	[
          	0,
          	1000000
          	]
          	],
          	"time" : [
          	[
          	{
          	"$maxElement" : 1
          	},
          	{
          	"$minElement" : 1
          	}
          	]
          	]
          	},
          	"server" : "node1:27017"
          }

          看到了沒有,雖然查詢時間縮短了,但是這個查詢結(jié)果還是會排序結(jié)果,好,我們再把索引改改:

          db.test.ensureIndex({type:1,sex:1,time:-1,id:1},{name:'index_tist'})

          {
          	"cursor" : "BtreeCursor index_tist",
          	"isMultiKey" : false,
          	"n" : 55556,
          	"nscannedObjects" : 55556,
          	"nscanned" : 55556,
          	"nscannedObjectsAllPlans" : 55657,
          	"nscannedAllPlans" : 55657,
          	"scanAndOrder" : false,
          	"indexOnly" : false,
          	"nYields" : 0,
          	"nChunkSkips" : 0,
          	"millis" : 168,
          	"indexBounds" : {
          	"type" : [
          	[
          	1,
          	1
          	]
          	],
          	"sex" : [
          	[
          	1,
          	1
          	]
          	],
          	"time" : [
          	[
          	{
          	"$maxElement" : 1
          	},
          	{
          	"$minElement" : 1
          	}
          	]
          	],
          	"id" : [
          	[
          	0,
          	1000000
          	]
          	]
          	},
          	"server" : "node1:27017"
          }

          再來看看,快到什么程度了,這個查詢的速度和參數(shù)條件已經(jīng)比上一個索引的快了很多,那為什么會出現(xiàn)這種情況呢?為什么time在id的前后會有不同的表現(xiàn)?這是因為通過type和sex字段過濾完之后,已經(jīng)在內(nèi)存中有了數(shù)據(jù),而這些數(shù)據(jù)下一步需要怎么辦?是先通過id來篩選,還是按照排序篩選呢?這里有一個知識點,在把id放在time前面時,程序首先會取復(fù)合id值,然后再把復(fù)合的數(shù)據(jù)排序,但是如果id放在排序的后面,那么程序?qū)⒅苯油ㄟ^順序掃描索引樹的方式取出復(fù)合id范圍的數(shù)據(jù)。

          四,總結(jié)


          1.mongodb創(chuàng)建索引難點在于排序和范圍查詢的字段位置選擇

          2.mongodb的復(fù)合索引的索引截取查詢是順序的,即如果(a:1,b:1,c:1},則可以是查詢{a:1},{a:1,b:1},{a:1,b:1,c:1}中得任何一種都會使用該索引,其它查詢情況將不會用到該索引;

          3.盡量創(chuàng)建更少的索引以提高數(shù)據(jù)庫性能

          4.以上的索引優(yōu)化只是生產(chǎn)環(huán)境的一部分,具體情況可能還要看自己的業(yè)務(wù)來定

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        關(guān)于mongodb創(chuàng)建索引的一些經(jīng)驗總結(jié)

        關(guān)于mongodb創(chuàng)建索引的一些經(jīng)驗總結(jié):想來接觸mongodb已經(jīng)快一年了,對于它的索引知識也積攢了不少經(jīng)驗,趁著這個月黑風(fēng)高的夜晚,就把mongodb的索引總結(jié)一番吧。 一,索引介紹 mongodb具有兩類索引,分別為單鍵索引和復(fù)合索引。 1.單鍵索引是最簡單的一種索引,創(chuàng)建單鍵索引的開銷要比復(fù)合索引
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 天堂在线免费观看中文版| 精品视频在线免费观看| 无码国产精品一区二区免费I6| 亚洲成av人在线视| a级毛片免费完整视频| 亚洲码国产精品高潮在线| 久久成人18免费网站| 亚洲成亚洲乱码一二三四区软件| 免费无码av片在线观看| 久久久亚洲精品无码| 无码av免费网站| 亚洲熟妇色自偷自拍另类| 黄页网站在线看免费| 亚洲欧美成人av在线观看| 成人无遮挡裸免费视频在线观看| 精品亚洲456在线播放| 日本19禁啪啪无遮挡免费动图| 色妞www精品视频免费看| 久久久久久A亚洲欧洲AV冫| 久久久久国产免费| 亚洲av日韩av无码av| 国产高清免费在线| 国产精品免费久久久久久久久| 亚洲av女电影网| 在线免费观看毛片网站| 国产免费播放一区二区| 久久久婷婷五月亚洲97号色| 免费H网站在线观看的| 黄色免费网址在线观看| 精品国产_亚洲人成在线高清| 久久久久久夜精品精品免费啦| 亚洲国产综合精品中文第一| 亚洲国产成人精品久久久国产成人一区二区三区综 | 人妻免费久久久久久久了| 亚洲精品成人无限看| 桃子视频在线观看高清免费完整| 亚洲日韩精品国产3区| 国产精品亚洲mnbav网站 | 免费黄色网址网站| 粉色视频成年免费人15次| 亚洲高清在线播放|