<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
        主站蜘蛛池模板: 亚洲熟妇无码八V在线播放| AA免费观看的1000部电影| 狼友av永久网站免费观看| 亚洲欧洲国产综合| 69视频在线观看高清免费| 91情国产l精品国产亚洲区| 免费一级不卡毛片| 久久精品视频亚洲| 亚洲精品免费视频| 亚洲国产高清在线精品一区| 成人午夜免费福利视频| 亚洲最大福利视频| 日本午夜免费福利视频| 无套内谢孕妇毛片免费看看| 亚洲色偷偷狠狠综合网| 国产免费一区二区三区免费视频 | 亚洲精品免费网站| 成人爽A毛片免费看| 亚洲av成人中文无码专区| 亚洲国产精品不卡毛片a在线| 久久国产精品免费一区| 亚洲A∨无码无在线观看| 色se01短视频永久免费| 亚洲国产无线乱码在线观看| 免费在线观看你懂的| 大地资源网高清在线观看免费| 久久99国产亚洲精品观看| 91视频国产免费| 草久免费在线观看网站| 亚洲国产二区三区久久| aa级一级天堂片免费观看| sihu国产精品永久免费| 久久精品国产亚洲av高清漫画| 岛国av无码免费无禁网站| 亚洲精品偷拍视频免费观看| 亚洲韩国—中文字幕| 国产性生交xxxxx免费| 特级做A爰片毛片免费看无码| 亚洲综合色区中文字幕| 亚洲AV无码成人精品区大在线| 久久久久久成人毛片免费看|