久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MongoDB數據庫中索引和explain的示例分析

159次閱讀
沒有評論

共計 7411 個字符,預計需要花費 19 分鐘才能閱讀完成。

這篇文章主要介紹了 MongoDB 數據庫中索引和 explain 的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓丸趣 TV 小編帶著大家一起了解一下。

mongodb 索引使用

作用

索引通常能夠極大的提高查詢。

索引是一種數據結構,他搜集一個集合中文檔特定字段的值。

B-Tree 索引來實現。

創建索引

db.collection.createIndex(keys, options)

keys

keys 由文檔字段和索引類型組成。如 {name :1}

key 表示字段 value 1,-1  1 表示升序,- 1 降序

options

options 創建索引的選項。

參數類型描述 backgroundboolean 創建索引在后臺運行,不會阻止其他對數據庫操作 uniqueboolean 創建唯一索引,文檔的值不會重復 namestring 索引名稱,默認是:字段名_排序類型 開始排序 sparseboolean 過濾掉 null,不存在的字段

查看索引

 db.collection.getIndexes()
 {
  v  : 1,
  key  : {
  _id  : 1
 },
  name  :  _id_ ,
  ns  :  leyue.userdatas 
 },
 {
  v  : 1,
  key  : {
  name  : 1 // 索引字段
 },
  name  :  name_1 , // 索引名稱
  ns  :  leyue.userdatas 
 }

刪除索引

  db.collection.dropIndex(index) 刪除指定的索引。

  db.collection.dropIndexes() 刪除除了_id 以外的所有索引。

index 是字符串 表示按照索引名稱 name 刪除字段。

index 是 {字段名稱:1} 表示按照 key 刪除索引。

創建 / 查看 / 刪除 示例

查看數據

 db.userdatas.find()
{  _id  : ObjectId( 597f357a09c84cf58880e412),  name  :  u3 ,  age  : 32 }
{  _id  : ObjectId( 597f357a09c84cf58880e411),  name  :  u4 ,  age  : 30,  score  : [ 7, 4, 2, 0 ] }
{  _id  : ObjectId( 597fcc0f411f2b2fd30d0b3f),  age  : 20,  score  : [ 7, 4, 2, 0, 10, 9, 8, 7 ],  name  :  lihao  }
{  _id  : ObjectId( 597f357a09c84cf58880e413),  name  :  u2 ,  age  : 33,  wendang  : {  yw  : 80,  xw  : 90 } }
{  _id  : ObjectId( 5983f5c88eec53fbcd56a7ca),  date  : ISODate(2017-08-04T04:19:20.693Z) }
{  _id  : ObjectId( 597f357a09c84cf58880e40e),  name  :  u1 ,  age  : 26,  address  :  中國碭山  }
{  _id  : ObjectId( 597f357a09c84cf58880e40f),  name  :  u1 ,  age  : 37,  score  : [ 10, 203, 12, 43, 56, 22 ] }
{  _id  : ObjectId( 597f357a09c84cf58880e410),  name  :  u5 ,  age  : 78,  address  :  china beijing chaoyang  }

給字段 name 創建索引

 //  創建索引
 db.userdatas.createIndex({name :1})
 {
  createdCollectionAutomatically  : false,
  numIndexesBefore  : 1,
  numIndexesAfter  : 2,
  ok  : 1
 }

 }  ]

給字段 name 創建索引并命名為 myindex

 db.userdatas.createIndex({name :1})
 db.userdatas.createIndex({name :1},{name : myindex})
 db.userdatas.getIndexes()
 [
 {
  v  : 1,
  key  : {
  _id  : 1
 },
  name  :  _id_ ,
  ns  :  leyue.userdatas 
 },
 {
  v  : 1,
  key  : {
  name  : 1
 },
  name  :  myindex ,
  ns  :  leyue.userdatas 
 }
 ]

給字段 name 創建索引 創建的過程在后臺執行

當 mongodb 集合里面的數據過大時 創建索引很耗時,可以在放在后臺運行。

 db.userdatas.dropIndex(myindex)
 db.userdatas.createIndex({name :1},{name : myindex , background :true})

給 age 字段創建唯一索引

 db.userdatas.createIndex({age :-1},{name : ageIndex , unique :true, sparse :true})
 db.userdatas.getIndexes()
 {
  v  : 1,
  key  : {
  _id  : 1
 },
  name  :  _id_ ,
  ns  :  leyue.userdatas 
 },
 {
  v  : 1,
  key  : {
  name  : 1
 },
  name  :  myindex ,
  ns  :  leyue.userdatas ,
  background  : true
 },
 {
  v  : 1,
  unique  : true,
  key  : {
  age  : -1
 },
  name  :  ageIndex ,
  ns  :  leyue.userdatas ,
  sparse  : true
 }
//  插入一個已存在的 age
 db.userdatas.insert({  name  :  u8 ,  age  : 32})

  code  : 11000,   errmsg  :  E11000 duplicate key error index: leyue.userdatas.$ageIndex dup key: { : 32.0 }  } })

創建復合索引

 db.userdatas.createIndex({name :1, age :-1})
 db.userdatas.getIndexes()
 {
  v  : 1,
  key  : {
  _id  : 1
 },
  name  :  _id_ ,
  ns  :  leyue.userdatas 
 },
 {
  v  : 1,
  key  : {
  name  : 1,
  age  : -1
 },
  name  :  name_1_age_-1 ,
  ns  :  leyue.userdatas 
 }
]

所有的字段都存在集合 system.indexes 中

db.system.indexes.find()
{  v  : 1,  key  : {  _id  : 1 },  name  :  _id_ ,  ns  :  leyue.userdatas  }
{  v  : 1,  key  : {  _id  : 1 },  name  :  _id_ ,  ns  :  leyue.scores  }
{  v  : 1,  key  : {  _id  : 1 },  name  :  _id_ ,  ns  :  leyue.test  }
{  v  : 1,  key  : {  user  : 1,  name  : 1 },  name  :  myindex ,  ns  :  leyue.test  }
{  v  : 1,  key  : {  _id  : 1 },  name  :  _id_ ,  ns  :  leyue.mycapped  }
{  v  : 1,  key  : {  user  : 1 },  name  :  user_1 ,  ns  :  leyue.test  }
{  v  : 1,  key  : {  name  : 1 },  name  :  myindex ,  ns  :  leyue.userdatas  }

索引總結

  1: 創建索引時,1 表示按升序存儲,- 1 表示按降序存儲。

  2: 可以創建復合索引, 如果想用到復合索引, 必須在查詢條件中包含復合索引中的前 N 個索引列

  3: 如果查詢條件中的鍵值順序和復合索引中的創建順序不一致的話,

  MongoDB 可以智能的幫助我們調整該順序, 以便使復合索引可以為查詢所用。

  4: 可以為內嵌文檔創建索引, 其規則和普通文檔創建索引是一樣的。

  5: 一次查詢中只能使用一個索引,$or 特殊, 可以在每個分支條件上使用一個索引。

  6: $where,$exists 不能使用索引, 還有一些低效率的操作符, 比如:$ne,$not,$nin 等。

  7: 設計多個字段的索引時, 應該盡量將用于精確匹配的字段放在索引的前面。

explain 使用

語法

 db.collection.explain(). method(...)

explain() 可以設置參數:

queryPlanner。

executionStats。

allPlansExecution。

示例

for(var i=0;i 100000;i++) { db.test.insert({ user : user +i});
}

沒有使用索引

 db.test.explain(executionStats).find({user : user200000})
  queryPlanner  : {
  plannerVersion  : 1,
  namespace  :  leyue.test ,
  indexFilterSet  : false,
  parsedQuery  : {
  user  : {
  $eq  :  user200000 
 }
 },
  winningPlan  : {
  stage  :  COLLSCAN ,
  filter  : {
  user  : {
  $eq  :  user200000 
 }
 },
  direction  :  forward 
 },
  rejectedPlans  : [ ]
 },
  executionStats  : {
  executionSuccess  : true,
  nReturned  : 2,
  executionTimeMillis  : 326,
  totalKeysExamined  : 0,
  totalDocsExamined  : 1006497,
  executionStages  : {
  stage  :  COLLSCAN ,
  filter  : {
  user  : {
  $eq  :  user200000 
 }
 },
  nReturned  : 2,
  executionTimeMillisEstimate  : 270,
  works  : 1006499,
  advanced  : 2,
  needTime  : 1006496,
  needYield  : 0,
  saveState  : 7863,
  restoreState  : 7863,
  isEOF  : 1,
  invalidates  : 0,
  direction  :  forward ,
  docsExamined  : 1006497
 }
 },
  serverInfo  : {
  host  :  lihaodeMacBook-Pro.local ,
  port  : 27017,
  version  :  3.2.1 ,
  gitVersion  :  a14d55980c2cdc565d4704a7e3ad37e4e535c1b2 
 },
  ok  : 1
}

executionStats.executionTimeMillis: query 的整體查詢時間。

executionStats.nReturned : 查詢返回的條目。

executionStats.totalKeysExamined:索引掃描條目。

executionStats.totalDocsExamined:文檔掃描條目。

executionTimeMillis = 326 query 執行時間

nReturned=2 返回兩條數據

totalKeysExamined=0 沒有用到索引

totalDocsExamined 全文檔掃描

理想狀態:

nReturned=totalKeysExamined totalDocsExamined=0

Stage 狀態分析

stage 描述 COLLSCAN 全表掃描 IXSCAN 掃描索引 FETCH 根據索引去檢索指定 documentSHARD_MERGE 將各個分片返回數據進行 mergeSORT 表明在內存中進行了排序 LIMIT 使用 limit 限制返回數 SKIP 使用 skip 進行跳過 IDHACK 針對_id 進行查詢 SHARDING_FILTER 通過 mongos 對分片數據進行查詢 COUNT 利用 db.coll.explain().count() 之類進行 count 運算 COUNTSCANcount 不使用 Index 進行 count 時的 stage 返回 COUNT_SCANcount 使用了 Index 進行 count 時的 stage 返回 SUBPLA 未使用到索引的 $or 查詢的 stage 返回 TEXT 使用全文索引進行查詢時候的 stage 返回 PROJECTION 限定返回字段時候 stage 的返回

對于普通查詢,我希望看到 stage 的組合 (查詢的時候盡可能用上索引):

  Fetch+IDHACK

  Fetch+ixscan

  Limit+(Fetch+ixscan)

  PROJECTION+ixscan

  SHARDING_FITER+ixscan

  COUNT_SCAN

不希望看到包含如下的 stage:

COLLSCAN(全表掃描),SORT(使用 sort 但是無 index), 不合理的 SKIP,SUBPLA(未用到 index 的 $or),COUNTSCAN(不使用 index 進行 count)

使用索引

 db.test.createIndex({user :1},{name : myindex , background :true})
 db.test.explain(executionStats).find({user : user200000})
  queryPlanner  : {
  plannerVersion  : 1,
  namespace  :  leyue.test ,
  indexFilterSet  : false,
  parsedQuery  : {
  user  : {
  $eq  :  user200000 
 }
 },
  winningPlan  : {
  stage  :  FETCH ,
  inputStage  : {
  stage  :  IXSCAN ,
  keyPattern  : {
  user  : 1
 },
  indexName  :  myindex ,
  isMultiKey  : false,
  isUnique  : false,
  isSparse  : false,
  isPartial  : false,
  indexVersion  : 1,
  direction  :  forward ,
  indexBounds  : {
  user  : [  [\ user200000\ , \ user200000\] 
 ]
 }
 }
 },
  rejectedPlans  : [ ]
 },
  executionStats  : {
  executionSuccess  : true,
  nReturned  : 2,
  executionTimeMillis  : 0,
  totalKeysExamined  : 2,
  totalDocsExamined  : 2,
  executionStages  : {
  stage  :  FETCH ,
  nReturned  : 2,
  executionTimeMillisEstimate  : 0,
  works  : 3,
  advanced  : 2,
  needTime  : 0,
  needYield  : 0,
  saveState  : 0,
  restoreState  : 0,
  isEOF  : 1,
  invalidates  : 0,
  docsExamined  : 2,
  alreadyHasObj  : 0,
  inputStage  : {
  stage  :  IXSCAN ,
  nReturned  : 2,
  executionTimeMillisEstimate  : 0,
  works  : 3,
  advanced  : 2,
  needTime  : 0,
  needYield  : 0,
  saveState  : 0,
  restoreState  : 0,
  isEOF  : 1,
  invalidates  : 0,
  keyPattern  : {
  user  : 1
 },
  indexName  :  myindex ,
  isMultiKey  : false,
  isUnique  : false,
  isSparse  : false,
  isPartial  : false,
  indexVersion  : 1,
  direction  :  forward ,
  indexBounds  : {
  user  : [  [\ user200000\ , \ user200000\] 
 ]
 },
  keysExamined  : 2,
  dupsTested  : 0,
  dupsDropped  : 0,
  seenInvalidated  : 0
 }
 }
 },
  serverInfo  : {
  host  :  lihaodeMacBook-Pro.local ,
  port  : 27017,
  version  :  3.2.1 ,
  gitVersion  :  a14d55980c2cdc565d4704a7e3ad37e4e535c1b2 
 },
  ok  : 1
}

executionTimeMillis: 0

totalKeysExamined: 2

totalDocsExamined:2

nReturned:2

stage:IXSCAN

使用索引和不使用差距很大,合理使用索引,一個集合適合做 4-5 個索引。

感謝你能夠認真閱讀完這篇文章,希望丸趣 TV 小編分享的“MongoDB 數據庫中索引和 explain 的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持丸趣 TV,關注丸趣 TV 行業資訊頻道,更多相關知識等著你來學習!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-04發表,共計7411字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 厦门市| 康定县| 涞源县| 咸丰县| 长葛市| 城步| 丹江口市| 柳河县| 南昌县| 开江县| 柞水县| 崇义县| 玛沁县| 红河县| 宿州市| 平江县| 阜阳市| 阿克苏市| 奇台县| 江北区| 石门县| 老河口市| 疏附县| 同心县| 贵港市| 石阡县| 迁安市| 龙南县| 瓦房店市| 平凉市| 台州市| 平江县| 东至县| 华阴市| 木兰县| 孝义市| 桃园市| 报价| 客服| 江北区| 铜川市|