溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

MongoDB 創(chuàng)建基礎(chǔ)索引、組合索引、唯一索引以及優(yōu)化

發(fā)布時(shí)間:2020-06-26 03:13:35 來(lái)源:網(wǎng)絡(luò) 閱讀:1363 作者:聽砜 欄目:編程語(yǔ)言

一、索引

MongoDB 提供了多樣性的索引支持,索引信息被保存在system.indexes 中,且默認(rèn)總是為_id創(chuàng)建索引,它的索引使用基本和MySQL關(guān)系型數(shù)據(jù)庫(kù)一樣。其實(shí)可以這樣說(shuō)說(shuō),索引是凌駕于數(shù)據(jù)存儲(chǔ)系統(tǒng)之上的另一層系統(tǒng),所以各種結(jié)構(gòu)迥異的存儲(chǔ)都有相同或相似的索引實(shí)現(xiàn)及使用接口并不足為 奇。

基礎(chǔ)索引

在字段age 上創(chuàng)建索引,1(升序);-1(降序):

db.users.ensureIndex({age:1})

_id 是創(chuàng)建表的時(shí)候自動(dòng)創(chuàng)建的索引,此索引是不能夠刪除的。當(dāng)系統(tǒng)已有大量數(shù)據(jù)時(shí),創(chuàng)建索引就是個(gè)非常耗時(shí)的活,我們可以在后臺(tái)執(zhí)行,只需指定“backgroud:true”即可。

db.users.ensureIndex({age:1} , {backgroud:true})

文檔索引

索引可以任何類型的字段,甚至文檔:

db.factories.insert( { name: "wwl", addr: { city: "Beijing", state: "BJ" } } );

在addr 列上創(chuàng)建索引

db.factories.ensureIndex( { addr : 1 } );

下面這個(gè)查詢將會(huì)用到我們剛剛建立的索引

db.factories.find( { addr: { city: "Beijing", state: "BJ" } } );

但是下面這個(gè)查詢將不會(huì)用到索引,因?yàn)椴樵兊捻樞蚋饕⒌捻樞虿灰粯?/p>

db.factories.find( { addr: { state: "BJ" , city: "Beijing"} } );

組合索引

跟其它數(shù)據(jù)庫(kù)產(chǎn)品一樣,MongoDB 也是有組合索引的,下面我們將在addr.city 和addr.state上建立組合索引。當(dāng)創(chuàng)建組合索引時(shí),字段后面的1 表示升序,-1 表示降序,是用1 還是用-1 主要是跟排序的時(shí)候或指定范圍內(nèi)查詢 的時(shí)候有關(guān)的。

db.factories.ensureIndex( { "addr.city" : 1, "addr.state" : 1 } );

下面的查詢都用到了這個(gè)索引

db.factories.find( { "addr.city" : "Beijing", "addr.state" : "BJ" } );

db.factories.find( { "addr.city" : "Beijing" } );

db.factories.find().sort( { "addr.city" : 1, "addr.state" : 1 } );

db.factories.find().sort( { "addr.city" : 1 } );

唯一索引

只需在ensureIndex 命令中指定”unique:true”即可創(chuàng)建唯一索引。例如,往表t4 中插入2 條記錄時(shí)候報(bào)錯(cuò)。

db.t4.ensureIndex({firstname: 1, lastname: 1}, {unique: true});

強(qiáng)制使用索引

hint 命令可以強(qiáng)制使用某個(gè)索引。

db.t5.find({age:{$lt:30}}).hint({name:1, age:1}).explain()

刪除索引

刪除t3 表中的所有索引

db.t3.dropIndexes()

刪除t4 表中的firstname 索引

db.t4.dropIndex({firstname: 1})

二、explain執(zhí)行計(jì)劃

MongoDB 提供了一個(gè) explain 命令讓我們獲知系統(tǒng)如何處理查詢請(qǐng)求。利用 explain 命令,我們可以很好地觀察系統(tǒng)如何使用索引來(lái)加快檢索,同時(shí)可以針對(duì)性優(yōu)化索引。

db.sang_collect.find({x:1}).explain()
# 返回值, 在python中運(yùn)行
{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "sang.sang_collect",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "x" : {
                "$eq" : 1.0
            }
        },
        "winningPlan" : {
            "stage" : "COLLSCAN",
            "filter" : {
                "x" : {
                    "$eq" : 1.0
                }
            },
            "direction" : "forward"
        },
        "rejectedPlans" : []
    },
    "serverInfo" : {
        "host" : "localhost.localdomain",
        "port" : 27017,
        "version" : "3.4.9",
        "gitVersion" : "876ebee8c7dd0e2d992f36a848ff4dc50ee6603e"
    },
    "ok" : 1.0
}

MongoDB 創(chuàng)建基礎(chǔ)索引、組合索引、唯一索引以及優(yōu)化
MongoDB 創(chuàng)建基礎(chǔ)索引、組合索引、唯一索引以及優(yōu)化
字段說(shuō)明:
MongoDB 創(chuàng)建基礎(chǔ)索引、組合索引、唯一索引以及優(yōu)化

executionStats

executionStats會(huì)返回最佳執(zhí)行計(jì)劃的一些統(tǒng)計(jì)信息,如下:

db.sang_collect.find({x:1}).explain('executionStats')

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "sang.sang_collect",
        "indexFilterSet" : false,
        "parsedQuery" : {},
        "winningPlan" : {
            "stage" : "COLLSCAN",
            "direction" : "forward"
        },
        "rejectedPlans" : []
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 10000,
        "executionTimeMillis" : 4,
        "totalKeysExamined" : 0,
        "totalDocsExamined" : 10000,
        "executionStages" : {
            "stage" : "COLLSCAN",
            "nReturned" : 10000,
            "executionTimeMillisEstimate" : 0,
            "works" : 10002,
            "advanced" : 10000,
            "needTime" : 1,
            "needYield" : 0,
            "saveState" : 78,
            "restoreState" : 78,
            "isEOF" : 1,
            "invalidates" : 0,
            "direction" : "forward",
            "docsExamined" : 10000
        }
    },
    "serverInfo" : {
        "host" : "localhost.localdomain",
        "port" : 27017,
        "version" : "3.4.9",
        "gitVersion" : "876ebee8c7dd0e2d992f36a848ff4dc50ee6603e"
    },
    "ok" : 1.0
}

這里除了我們上文介紹到的一些參數(shù)之外,還多了executionStats參數(shù),含義如下:
MongoDB 創(chuàng)建基礎(chǔ)索引、組合索引、唯一索引以及優(yōu)化

三、優(yōu)化器profile

在MySQL 中,慢查詢?nèi)罩臼墙?jīng)常作為我們優(yōu)化數(shù)據(jù)庫(kù)的依據(jù),那在MongoDB 中是否有類似的功能呢?答案是肯定的,那就是MongoDB Database Profiler。

開啟profiling功能

有兩種方式可以控制 Profiling 的開關(guān)和級(jí)別,第一種是直接在啟動(dòng)參數(shù)里直接進(jìn)行設(shè)置。啟動(dòng)MongoDB 時(shí)加上–profile=級(jí)別 即可。也可以在客戶端調(diào)用db.setProfilingLevel(級(jí)別) 命令來(lái)實(shí)時(shí)配置,Profiler 信息保存在system.profile 中。我們可以通過(guò)db.getProfilingLevel()命令來(lái)獲取當(dāng)前的Profile 級(jí)別,類似如下操作:

db.setProfilingLevel(2);

上面profile 的級(jí)別可以取0,1,2 三個(gè)值,他們表示的意義如下:

0 – 不開啟

1 – 記錄慢命令 (默認(rèn)為>100ms)

2 – 記錄所有命令

Profile 記錄在級(jí)別1 時(shí)會(huì)記錄慢命令,那么這個(gè)慢的定義是什么?上面我們說(shuō)到其默認(rèn)為100ms,當(dāng)然有默認(rèn)就有設(shè)置,其設(shè)置方法和級(jí)別一樣有兩種,一種是通過(guò)添加 –slowms 啟動(dòng)參數(shù)配置。第二種是調(diào)用db.setProfilingLevel 時(shí)加上第二個(gè)參數(shù):

db.setProfilingLevel( level , slowms )

db.setProfilingLevel( 1 , 10 );

查詢 Profiling 記錄

與MySQL 的慢查詢?nèi)罩静煌?,MongoDB Profile 記錄是直接存在系統(tǒng)db 里的,記錄位置system.profile ,所以,我們只要查詢這個(gè)Collection 的記錄就可以獲取到我們的 Profile 記錄了。列出執(zhí)行時(shí)間長(zhǎng)于某一限度(5ms)的 Profile 記錄:

db.system.profile.find( { millis : { $gt : 5 } } )

MongoDB Shell 還提供了一個(gè)比較簡(jiǎn)潔的命令show profile,可列出最近5 條執(zhí)行時(shí)間超過(guò)1ms 的 Profile 記錄。

四、常用性能優(yōu)化方案

創(chuàng)建索引, 當(dāng)查詢的字段有2個(gè)時(shí),數(shù)據(jù)量較大時(shí),可以使用聯(lián)合索引

限定返回結(jié)果數(shù)

只查詢使用到的字段

采用capped collection

采用Server Side Code Execution

使用Hint,強(qiáng)制使用索引

采用Profiling

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI