1. 程式人生 > >MongoDB學習04: 索引

MongoDB學習04: 索引

資料量較大時,使用索引可以大大加快查詢速度。
- 檢視索引
db.test_collection.getIndexes()
- 建立索引
db.test_collection.ensureIndex({x:1})

索引種類

  • _id 索引(自動建立)
  • 單鍵索引(比較變通的索引,不會自動建立)
  • 多鍵索引(與單。。區別在於欄位的值是單一,還是陣列)
    db.test_collection.ensureIndex({x:1})
    db.test_collection.insert({x:[1,4,5,4]}) //就成了多鍵索引
  • 複合索引(當查詢條件不只一個時,就需要建立複合索引)
    db.collection.ensureIndex({x:1,y:1})
  • 過期索引(一段時間會過期,相應資料也會被刪除)
    比較適合登入資訊和日誌資訊。
    db.collection.ensureIndex({time:1},{expireAfterSeconds:10})
    儲存在過期索引的值必須是指定的時間型別,必須是ISODate或者ISODate陣列,不能使用時間戳,否則不能被自動刪除 ;如果ISODate是陣列,則最小時間進行刪除;不能是複合索引;刪除時間是不精確的(每60s跑一次,刪除也要一些時間)。
  • 全文索引(對字串與字串陣列建立全文可搜尋的索引)
    適用情況:{author:”“,title:”“,article:”“}
    db.articles.ensureIndex({key:"text"})

    db.articles.ensureIndex({key1:"text",key2:"text"})
    db.articles.ensureIndex({key:"text"})
    查詢:
    db.articles.find({$text:{$search:"coffee"}})
    db.articles.find({$text:{$search:"aa bb cc"}}) //或查詢
    db.articles.find({$text:{$search:"aa bb -cc"}}) //不包含cc串
    db.articles.find({$text:{$search:"\"aa\" \"bb\" \"cc\""}}) //與查詢語句,用引號(這裡要用斜線轉義)

    與百度查詢相同,相似度越大的在前面的查詢(使用$meta):
    {score:{$meta:"textScore"}}
    db.articles.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}})查詢資料中多了一個score欄位,表示相似度
    進行排序:
    db.articles.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})
    使用限制:每次查詢只能指定一個 text text查詢不能出現在 nor text,hint不再起作用(強制指定使用某索引進行效能測試);不支援中文。
  • 地理位置索引
    將一些點的位置儲存在MongoDB中,建立索引後,可以按照位置來查詢其他點。
    子分類:

    1. 2d索引,用於儲存和查詢平面上的點;
      查詢方式:
      a. 查詢距離某個點一定距離內的點。
      ensureIndex({w:"2d"}) //建立
      經度[-180,180]緯度[-90,90]
      insert({w:[1,1]}) //插入資料
      find({w:{$near:[1,1]}}) //與[1,1]距離最近的點
      find({w:{$near:[1,1],$maxDistance:10}}) // 設定最大距離範圍
      b. 查詢包含在某個區域內的點。
      find({w:{$geoWithin:{$box:[[0,0],[3,3]]}}}) //在矩形中的點
      find({w:{$geoWithin:{$center:[[0,0],4]}}}) //在圓中的點
      find({w:{$geoWithin:{$polygon:[[0,0],[0,1],[2,5],[6,1]]}}}) //在多邊形中的點
      geoNear查詢:
      db.runCommand({geoNear:<collection>,near:[x,y],minDistance:d1,maxDistance:d2,num:n1(返回數目)})
      db.runCommand({geoNear:"location",near:[1,2],maxDistance:10,num:2})

    2. 2dsphere索引,用於儲存和查詢球面上的點。
      ensureIndex({w:"2dsphere"})
      {type:" ",coordinates:[<coodinates>]} //位置表示
      查詢與2d類似,並且支援$minDistance 與 $maxDistance,還支援交叉點

索引屬性

  • name
    一般索引 x_1 或x_-1//升序與降序 ;複合索引為x_1_y_-1;可能超125位元組限制自定義索引名字:ensureIndex({x:1,y:1,z:1,m:1},{name:"normal_index
  • 唯一性,unique指定:
    ensureIndex({},{unique:true/false})
  • 稀疏性,sparse指定(在不包括索引資料中不必建立索引,節約空間,增大查詢速度):
    ensureIndex({},{sparse:true})
    但在$exists(用於查詢一個欄位存在與不存在的資料)中出現隱患
    find({m:{$exists:true}}) //只查詢m存在的欄位
    不能在稀疏索引上查詢不存在的記錄。
  • 是否定期刪除,expireAfterSeconds指定:
    TTL,過期索引

索引構建情況分析

  • 好處:加快索引相關的查詢。
  • 劣勢:增加磁碟空間消耗,降低寫入效能。

評判當前索引構建情況

  • mongostat工具
    mongostat -h 127.0.0.1:12345
    其中 idx miss 較高,就說明建立了不合適的索引
    各指標含義:
    inserts/s 每秒插入次數
    query/s 每秒查詢次數
    update/s 每秒更新次數
    delete/s 每秒刪除次數
    getmore/s 每秒執行getmore次數
    command/s 每秒的命令數,比如count
    flushs/s 每秒執行fsync將資料寫入硬碟的次數。
    mapped/s 所有的被mmap的資料量,單位是MB,
    vsize 虛擬記憶體使用量,單位MB
    res 實體記憶體使用量,單位MB
    faults/s 每秒訪問失敗數(只有Linux有),資料被交換出實體記憶體,放到swap。不要超過100,否則就是機器記憶體太小,造成頻繁swap寫入。此時要升級記憶體或者擴充套件
    locked % 被鎖的時間百分比,儘量控制在50%以下吧
    idx miss % 索引不命中所佔百分比。如果太高的話就要考慮索引是不是少了
    q t|r|w 當Mongodb接收到太多的命令而資料庫被鎖住無法執行完成,它會將命令加入佇列。這一欄顯示了總共、讀、寫3個佇列的長度,都為0的話表示mongo毫無壓力。高併發時,一般佇列值會升高。
    conn 當前連線數
    time 時間戳
    Mongodb良好執行標示:
    insert query update delete 較穩定,這4列資料越大說明效能越高,如果執行一定時間後,指標驟減,說明程式處理存在問題。
    faults越小越好,越小說明操作失敗率越低;
    idx miss越小越好,越小說明索引命中率越高,Mongodb索引非常重要;
    netin/netout 資料越大越好,越大說明進出資料交換越大。
  • profile集合介紹
    db.getProfilingLevel() //有0關閉,2開啟,1記錄超過slowms值的操作
    db.getProfilingStatus()// { "was" : 0, "slowms" : 100 }
    設定db.setProfilingLevel(2)//開啟,會生成一個system.profile文件
    db.system.profile.find().sort({$natural:-1}).limit(1)
    開啟後會影響到資料庫的效能,只適用於系統的測試階段和剛剛上線時觀察階段。
  • 日誌介紹
    在配置檔案mongod.conf下verbose=vvvvvverbose值可以是一個v到五個v.詳細程度逐漸提高
  • explain分析
    find({x:1}).explain()可以查詢你的查詢是否用了索引和查詢時間,以及掃描數量。