<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          mongodb-索引

          共 3896字,需瀏覽 8分鐘

           ·

          2022-04-23 21:42


          • 前言

          • mongo 的索引數(shù)據(jù)結(jié)構(gòu)是什么

          • mongo 中支持哪些索引類型

            • 單個(gè)索引

            • 復(fù)合索引

            • 多鍵索引

            • 地理空間索引

            • 文本索引

            • Hashed索引

          • 索引特性

            • 唯一索引

            • 部分索引

            • 稀疏索引

            • TTL索引

            • 覆蓋索引

            • 前綴索引

          • 使用索引的奇淫技巧

            • 組合索引的最佳方式 ESR 原則

            • 合理使用部分索引

            • 后臺(tái)創(chuàng)建索引

          • 怎么查看我到有沒(méi)有用到索引?


          前言

          索引的重要性在數(shù)據(jù)庫(kù)中是不言而喻的,mysql 中使用了 B+ 數(shù)來(lái)當(dāng)做索引的數(shù)據(jù)結(jié)構(gòu),為 mysql 性能提升做了很大的貢獻(xiàn),那么在 mongoDB 中又使用了什么數(shù)據(jù)結(jié)構(gòu)呢?今天就和大家聊聊 mongoDB 的索引

          • mongoDB 的索引數(shù)據(jù)結(jié)構(gòu)是什么?
          • mongoDB 支持哪些索引類型?
          • 索引奇淫技巧 ?
          • 怎么查看我到有沒(méi)有用到索引?

          mongo 的索引數(shù)據(jù)結(jié)構(gòu)是什么

          網(wǎng)上對(duì) mongoDB 的數(shù)據(jù)結(jié)構(gòu)有很多種說(shuō)法,有說(shuō) B- 樹(shù)的,有說(shuō) B 樹(shù)的,還有說(shuō) B+ 樹(shù)的

          這里先說(shuō)一個(gè)常識(shí)性的誤區(qū),「沒(méi)有 B 減樹(shù)」,B-tree 其實(shí)就是 B 樹(shù),中間的破折號(hào)只是用來(lái)連接而已,「只有 B 樹(shù)和 B+ 樹(shù)」

          官方文檔明確說(shuō)到,在 WiredTiger 存儲(chǔ)引擎當(dāng)中,可以支持 B-Tree 和 LSM 兩種結(jié)構(gòu)組織數(shù)據(jù),「默認(rèn)使用 B+ 樹(shù)」的數(shù)據(jù)結(jié)構(gòu)在內(nèi)存中維護(hù)表的數(shù)據(jù),說(shuō) B 樹(shù)也沒(méi)錯(cuò),因?yàn)?B+ 樹(shù)就是 B 樹(shù)的子集

          對(duì)于 WiredTiger 存儲(chǔ)引擎來(lái)說(shuō),集合所在的數(shù)據(jù)文件和相應(yīng)的索引文件都是按 B-Tree 結(jié)構(gòu)來(lái)組織的,不同之處在于數(shù)據(jù)文件對(duì)應(yīng)的 B 樹(shù)葉子結(jié)點(diǎn)上除了存儲(chǔ)鍵名外(keys),還會(huì)存儲(chǔ)真正的集合數(shù)據(jù)(values),所以數(shù)據(jù)文件的存儲(chǔ)結(jié)構(gòu)也可以認(rèn)為是一種 B+Tree

          mongo 中支持哪些索引類型

          單個(gè)索引

          簡(jiǎn)而言之就是單個(gè)字段的索引,比如

          db.children.createIndex({?age?:?1?})

          就相當(dāng)于給 children 表的 age 字段建立了一個(gè)升序索引 (升序 ( 1) 或降序 ( -1) )

          復(fù)合索引

          符合索引其實(shí)就是多個(gè)字段自合成一個(gè)索引,比如

          db.children.createIndex({?age?:?1,height?:?1?})

          就相當(dāng)于給 children 表 ?以 age 字段升序 height 字段升序建立了一個(gè)索引

          多鍵索引

          在MongoDB中可以「基于數(shù)組來(lái)創(chuàng)建索引」。MongoDB為數(shù)組每一個(gè)元素創(chuàng)建索引值。多鍵索引支持?jǐn)?shù)組字段的高效查詢,比如

          ([{?_id:?1,?name:?"xiaohong",?age:?"1",?ratings:?[?1,?2,?3?]?})
          db.children.createIndex(?{?ratings:?1?}?)

          但是對(duì)于一個(gè)復(fù)合多鍵索引,「每個(gè)索引最多可以包含一個(gè)數(shù)組」。比如以下情況就無(wú)法建立索引

          ([{?_id:?1,?name:?"xiaohong",?age:?"1",?ratings:?[?1,?2,?3?],teams:[?1?,?3?,?4]?})
          db.children.createIndex(?{?ratings:?1?,teams?:?-1}?)

          地理空間索引

          為了支持對(duì)地理空間坐標(biāo)數(shù)據(jù)的高效查詢,MongoDB提供了兩個(gè)特殊的索引:在返回結(jié)果時(shí)使用平面幾何的2d索引和使用球面幾何返回結(jié)果的2dsphere索引。有關(guān)地理空間索引的高級(jí)介紹,請(qǐng)參見(jiàn)2d Index Internals。

          文本索引

          MongoDB提供了一種文本索引類型,它支持搜索集合中的字符串內(nèi)容。這些文本索引不存儲(chǔ)特定于語(yǔ)言的停止詞(例如**“the”,“a”,“or”**),并且在一個(gè)集合中只存儲(chǔ)根詞的詞干。有關(guān)文本索引和搜索的更多信息,請(qǐng)參見(jiàn)文本索引。

          Hashed索引

          為了支持基于Hashed的分片,MongoDB提供了Hashed索引類型,該索引類型對(duì)字段值的Hashed進(jìn)行索引。這些索引在其范圍內(nèi)具有更隨機(jī)的值分布,但只支持相等匹配,而不支持基于范圍的查詢。

          索引特性

          唯一索引

          在創(chuàng)建集合期間,MongoDB 在_id字段上創(chuàng)建唯一索引,這也是默認(rèn)的唯一索引。該索引主要是為了區(qū)分文檔并且不能刪除。創(chuàng)建方式就是加上 unique: true

          db.children.createIndex(?{?age?:?1?},?{?unique:?true?}?)

          部分索引

          部分索引僅索引集合中符合指定過(guò)濾器表達(dá)式的文檔。

          比如 children 表中,將 age 大于 5 數(shù)據(jù)創(chuàng)建一個(gè)升序索引

          db.children.createIndex(
          {age:1},
          {partialFilterExpression:?{age:?{$gt:5}}})

          建立部分索引可以節(jié)省存儲(chǔ)空間,提升索引查詢效率。比如該文檔 2000 年前的數(shù)據(jù)為垃圾數(shù)據(jù),不常用,那就可以根據(jù)時(shí)間大于 2000 年創(chuàng)建索引

          稀疏索引

          索引的稀疏屬性可確保索引僅包含具有索引字段的文檔的條目。索引會(huì)跳過(guò)沒(méi)有索引字段的文檔。創(chuàng)建方式就是加上 sparse: true

          db.children.createIndex(?{?"age":?1?},?{?sparse:?true?}?)

          TTL索引

          TTL 索引是 MongoDB 可以使用的特殊索引,它可以在一定時(shí)間后自動(dòng)從集合中刪除文檔。

          db.children.createIndex(?{?"lastModifiedDate":?1?},?{?expireAfterSeconds:?5?}?)

          以上案例就是設(shè)置 5 秒后過(guò)去,使用方式只需要?jiǎng)?chuàng)建索引時(shí)加上 expireAfterSeconds: 5

          覆蓋索引

          所有需要查詢的數(shù)據(jù)都在索引當(dāng)中,不需要從數(shù)據(jù)頁(yè)中再去尋找數(shù)據(jù)

          比如我此時(shí)為?children?表的時(shí)間創(chuàng)建了一個(gè)索引
          db.children.createIndex({?age?:?1?})
          在此時(shí)我查找年齡為兩歲的孩子時(shí),就不需要從數(shù)據(jù)頁(yè)中去尋找數(shù)據(jù)了
          db.children.find({?age?:?2?})

          前綴索引

          所有的前綴索引都可以被這條索引所覆蓋,不需要再去針對(duì)這些前綴建立額外的索引,避免額外的開(kāi)銷

          比如我此時(shí)為 children 表的時(shí)間創(chuàng)建了「一個(gè)復(fù)合索引(多字段索引)」

          db.children.createIndex({?age?:?1,name?:?1,address?:?1})

          「那么其實(shí)這條索引等價(jià)于三條索引」,分別是

          db.children.createIndex({?age?:?1?})
          db.children.createIndex({?age?:?1,name?:?1?})
          db.children.createIndex({?age?:?1,name?:?1,address?:?1})

          使用索引的奇淫技巧

          組合索引的最佳方式 ESR 原則

          • 1.精準(zhǔn)匹配(Equal)的放前面
          • 2.排序(Sort)的放中間
          • 3.范圍匹配(Range)的方最后

          比如一條查詢語(yǔ)句

          db.largeClass.find({className:"a",age:{$gte:5}}).sort(time:1)

          最好的索引建立就應(yīng)該是 {className:1,time:1,age:1}

          E 放在最前面大家應(yīng)該都能理解,用等值匹配去過(guò)濾掉大量數(shù)據(jù),「那為什么是 ESR 不是 ERS 呢?」

          原因就是因?yàn)槿绻秶ヅ浞旁谥虚g,那么后續(xù)我們排序的時(shí)候只能進(jìn)行「內(nèi)存排序」,而內(nèi)存排序又是很消耗資源的,數(shù)據(jù)量大時(shí)可能會(huì)「面對(duì)著多次的磁盤(pán)讀取刷內(nèi)存操作」,非常的消耗時(shí)間

          合理使用部分索引

          對(duì)于有些比較大的文檔,可能很多數(shù)據(jù)都是無(wú)用的,比如文檔中有三年的數(shù)據(jù),但是業(yè)務(wù)只需要最近一年的數(shù)據(jù),那么就可以只根據(jù)時(shí)間對(duì)最近一年的數(shù)據(jù)建立索引

          后臺(tái)創(chuàng)建索引

          記得在創(chuàng)建索引時(shí)加上 {background: true},在后臺(tái)創(chuàng)建索引,防止影響 mongoDB 的正常工作,讓其自動(dòng)調(diào)配創(chuàng)建時(shí)間

          怎么查看我到有沒(méi)有用到索引?

          在 mongoDB 中提供了 「explain 執(zhí)行計(jì)劃」,可以清晰的看到你當(dāng)前的查詢語(yǔ)句時(shí)候有使用到索引,使用方式也很簡(jiǎn)單,只要在查詢語(yǔ)句右面加上 .explain 就可以了,有幾個(gè)「比較重要的屬性」在這里說(shuō)下

          「executionTimeMillis」:指的是我們這條語(yǔ)句的執(zhí)行時(shí)間
          「docsExamined」:文檔掃描數(shù)
          「totalDocsExamined」:文檔掃描條目
          「totalKeysExamined」:索引掃描條目
          「stage」:掃描類型,主要有

          COLLSCAN:全表掃描
          IXSCAN:索引掃描
          FETCH:根據(jù)索引去檢索指定document
          SHARD_MERGE:將各個(gè)分片返回?cái)?shù)據(jù)進(jìn)行merge
          SORT:表明在內(nèi)存中進(jìn)行了排序
          LIMIT:使用limit限制返回?cái)?shù)
          SKIP:使用skip進(jìn)行跳過(guò)
          IDHACK:針對(duì)_id進(jìn)行查詢
          SHARDING_FILTER:通過(guò)mongos對(duì)分片數(shù)據(jù)進(jìn)行查詢
          COUNT:利用db.coll.explain().count()之類進(jìn)行count運(yùn)算
          COUNTSCAN:count不使用Index進(jìn)行count時(shí)的stage返回
          COUNT_SCAN:count使用了Index進(jìn)行count時(shí)的stage返回
          SUBPLA:未使用到索引的$or查詢的stage返回
          TEXT:使用全文索引進(jìn)行查詢時(shí)候的stage返回
          PROJECTION:限定返回字段時(shí)候stage的返回

          所以當(dāng) 「stage 為 IXSCAN」 的時(shí)候就是使用到了索引掃描

          瀏覽 49
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲一级二级三级 | 一级黄色电影免费观看 | 三级国产在线观看 | 99精品在线免费观看 | 国产女人18毛片水18精品软件 |