語句集合
| 語句 | 功能 | 備注 |
|---|---|---|
| db.name. getIndexes() | 查詢索引 | |
| db.name.totalIndexSize() | 查詢索引大小 | |
| db.name.dropIndex("indexName") | 刪除索引 | |
| db.name.dropIndex(‘*’) | 刪除name集合中的所有索引 | _id索引不會刪除 |
| 沒有修改索引的方法 | 如果想想修改索引 | 先刪除舊索引,再重新創(chuàng)建索引 |
| db.name.ensureIndex() | 創(chuàng)建索引 |
索引種類
| 種類 | 解釋 | 備注 |
|---|---|---|
| 默認索引 | Mongodb每個collection都會有一個默認主鍵_id,這個不能刪除、也不會更名。當collection創(chuàng)建后,系統(tǒng)會自動創(chuàng)建一個”id”的索引,這個也是無法刪除與更名的 | |
| 單列索引 | 在單個欄位上創(chuàng)建的索引 | eg:需要對Mail的read創(chuàng)建升序索引:db.Mail.ensureIndex({‘read’:1}) |
| 組合索引 | 對多個鍵創(chuàng)建的索引 | eg:需要對Mail的user與folderId創(chuàng)建降序索引:db.Mail.ensureIndex({‘user’:-1,’folderId’:-1}) |
| 子文檔索引 | 可以為內(nèi)嵌文檔的鍵創(chuàng)建索引,這種與普通索引沒有什么區(qū)別 | eg:需要對Mail中的attachments下的filename創(chuàng)建索引: db.Mail.ensureIndex({‘a(chǎn)ttachments.filename’:1}) 注意:attachments.filename必須位于’’之中,否則會報錯 |
| 唯一索引 | 唯 一索引可能確保collection的每一個document指定的鍵的唯一性。當文檔不存在指定鍵時,會被認為鍵值是“null”,所以“null”也 會被認為是重復的,所以一般被作為唯一索引的鍵,最好都要有鍵值對 | 要保證Mail中每個用戶的mailfilename的唯一性:db.Mail.ensureIndex({‘user’:1,‘filename’:1},{name:’index1’,‘unique’:true}) 當為已有的collection增加唯一索引時,可能會有數(shù)據(jù)已經(jīng)重復了。有時候可能希望將所有包含重復的文檔都刪除,可能在創(chuàng)建唯一索引時,使用dropDups選項: db.Mail.ensureIndex({‘user’:1,‘filename’:1},{‘unique’:true,’dropDups’:true}) 這個會將重復的數(shù)據(jù)只保留一份,不過有點魯莽,如果數(shù)據(jù)很重要的話,建議不好這樣做。 注意了: Insert并不檢查文檔是否插入過,所以確保數(shù)據(jù)的唯一性,可能要用安全模式插入才行。這樣,在插入時,如果有重復就會有錯誤提醒 |
| Sparse索引 | Sparse index解決索引文件過大的問題,有時候我們要索引的某個屬性并非是所有記錄都有,普通的索引是將所有的記錄都包含進來,而sparse索引則僅包含含 有這個屬性的記錄,它不會對該項值為空的行作索引。這樣就大大減小了某些列的索引大小。目前的限制是,sparse index只能包含一個屬性。 | eg:在Mail中有個標簽屬性labels,這個屬性是唯一的,且有值的情況也不多,這種情況就最適合用sparse索引 了,創(chuàng)建索引的命令為: db.Mail.ensureIndex({labels:1},{sparse:true}) |
| Covered 索引 | 如果你查找的值正好是在索引中,則可以直接返回索引中存的值,而不用到數(shù)據(jù)文件中查找。(這個在傳統(tǒng)關系型數(shù)據(jù)庫中也有實現(xiàn)),不過,必須滿足以下條件: 1:必須提供準備的返回字段,以便可以直接從索引庫中查詢 2:必須明確地排除使用_id字段{_id:0}當用explain時,當indexOnly=true,表示有用到covered index |
// do a login with a covered index, returning the users roles/groups > db.users.ensureIndex( { username : 1, password : 1, roles : 1} ); > db.users.save({username: "joe", password: "pass", roles: 2}) > db.users.save({username: "liz", password: "pass2", roles: 4}) > db.users.find({username: "joe"}, {_id: 0, roles: 1}) { "roles" : 2 } > db.users.find({username: "joe"}, {_id: 0, roles: 1}).explain() { "cursor" : "BtreeCursor username_1_password_1_roles_1", ... "indexOnly" : true, ... } |
索引觸發(fā)條件
索引命中:
假設索引為:
{a:1,b:1,c:1,d:1}:
實際上是有了下列索引
{a:1},{a:1,b:1},{a:1,b:1,c:1},{a:1,b:1,c:1,d:1}
但是使用{b:1}、{a:1,c:1}等索引的查詢是會被優(yōu)化的,只有使用索引前部的查詢才能使用該索引。
Mongodb的查詢優(yōu)化器會重排查詢項的順序,以便命中索引,比如:查詢{x:’a’,y:’b’}的時候,如果已有了{y:1,x:1}的索引,mongodb也會自己找到并命中的。
創(chuàng)建索引的缺點是每次插入、更新與刪除時都會產(chǎn)生額外的開銷,這是因為數(shù)據(jù)庫不但需要執(zhí)行這些操作,還是處理索引,因些,要盡量可能少創(chuàng)建索引。每個集合默認的最大索引個數(shù)為64個。
查詢時,不要使用$ne or $nin,這樣不能命中索引
使用explain查看
db.collection.find(query).explain();
返回的信息如下
{“cursor” : “BasicCursor”,
“indexBounds” : [ ],
“nscanned” : 57594,
“nscannedObjects” : 57594,
“nYields” : 2 ,
“n” : 3 ,
“millis” : 108,
“indexOnly” : false}
現(xiàn)實結(jié)果可以得知cursor的類型,DB掃描的數(shù)據(jù)數(shù),返回的數(shù)據(jù)數(shù),還有執(zhí)行的毫秒數(shù)。
“cursor” : “BasicCursor”:
命中的索引,當為BasicCursor時表示沒有命中任何索引
indexBounds: 所使用的索引,被設置為表示為索引掃描的關鍵邊界。
nscanned – 掃描的數(shù)據(jù)條數(shù)。
nscannedObjects – 掃描對象的數(shù)。
nYields – 查詢所產(chǎn)生的鎖的個數(shù)。
isMultiKey- MongoDB中提供了可以自動索引數(shù)組對象的值
If true, a multikey index was used.
n- 返回文檔的數(shù)量
millis- 數(shù)據(jù)庫中執(zhí)行查詢的時間
indexOnly – 是否使用了covered index。