zoukankan      html  css  js  c++  java
  • MongoDB基础之六 索引

    一 . 索引概述和基本操作

    1. 索引提高查询速度,降低写入速度,权衡常用的查询字段,不必在太多列上建索引
    2. 在mongodb中,索引可以按字段升序/降序来创建,便于排序
    3. 默认是用btree来组织索引文件,2.4版本以后,也允许建立hash索引.

    常用命令:
    查看当前索引状态: db.collection.getIndexes();

    创建普通的单列索引:db.collection.ensureIndex({field:1/-1}); 1是升续 2是降续

    删除单个索引
    db.collection.dropIndex({filed:1/-1});

    一下删除所有索引
    db.collection.dropIndexes();

    创建多列索引 db.collection.ensureIndex({field1:1/-1, field2:1/-1});

     

    例子: 

     1 > for (var i = 1;i<=1000;i++){
     2 ... db.stu.insert({sn:i,name:'student'+i})
     3 ... };
     4 > 
     5 > 
     6 > db.stu.find().count();
     7 1000
     8 > db.stu.find({sn:99});
     9 { "_id" : ObjectId("574271a9addef29711337c28"), "sn" : 99, "name" : "student99" }
    10 > db.stu.find({sn:99}).explain();
    11 {
    12 "cursor" : "BasicCursor", -- 无索引相当于mysql的全表扫描
    13 "isMultiKey" : false, 
    14 "n" : 1,
    15 "nscannedObjects" : 1000, -- 扫描了1000行
    16 ....
    17 
    18 > db.stu.ensureIndex({sn:1}); --创建索引
    19 > db.stu.find({sn:99}).explain();
    20 {
    21 "cursor" : "BtreeCursor sn_1", --使用了索引
    22 "isMultiKey" : false,
    23 "n" : 1,
    24 "nscannedObjects" : 1, --只用扫描一行
    25 ...
    26 }
    27 
    28 
    29 > db.stu.getIndexes(); --查询索引
    30 [
    31 {
    32 "v" : 1,
    33 "key" : {
    34 "_id" : 1 -- 默认创建 正序
    35 },
    36 "ns" : "test.stu",
    37 "name" : "_id_"
    38 },
    39 {
    40 "v" : 1,
    41 "key" : {
    42 "sn" : 1
    43 },
    44 "ns" : "test.stu",
    45 "name" : "sn_1"
    46 }
    47 ]
    48 
    49 
    50 > db.stu.ensureIndex({sn:1,name:1});
    51 > 
    52 > 
    53 > db.stu.getIndexes();
    54 [
    55 {
    56 "v" : 1,
    57 "key" : {
    58 "_id" : 1
    59 },
    60 "ns" : "test.stu",
    61 "name" : "_id_"
    62 },
    63 {
    64 "v" : 1,
    65 "key" : {
    66 "sn" : 1
    67 },
    68 "ns" : "test.stu",
    69 "name" : "sn_1"
    70 },
    71 {
    72 "v" : 1,
    73 "key" : {
    74 "sn" : 1,
    75 "name" : 1
    76 },
    77 "ns" : "test.stu",
    78 "name" : "sn_1_name_1"
    79 }
    80 ]

    二. 子文档索引

         指向下级嵌套的文档的索引

     1 > db.shop.insert({name:'Nokia',spc:{weight:120,area:'taiwan'}});
     2 > db.shop.insert({name:'Nokia',spc:{weight:100,area:'korea'}});
     3 
     4 > db.shop.find({'spc.area':'taiwan'});
     5 { "_id" : ObjectId("5743d662addef29711337fb0"), "name" : "Nokia", "spc" : { "weight" : 120, "area" : "taiwan" } }
     6 
     7 
     8 > db.shop.ensureIndex({'spc.area,1'});
     9 Tue May 24 12:29:58.823 SyntaxError: Unexpected token }
    10 > db.shop.ensureIndex({'spc.area':1});
    11 > 
    12 > db.shop.getIndexes();
    13 [
    14 {
    15 "v" : 1,
    16 "key" : {
    17 "_id" : 1
    18 },
    19 "ns" : "test.shop",
    20 "name" : "_id_"
    21 },
    22 {
    23 "v" : 1,
    24 "key" : {
    25 "spc.area" : 1
    26 },
    27 "ns" : "test.shop",
    28 "name" : "spc.area_1"
    29 }
    30 ]
    31 >

     

    三.  唯一索引

     1 > show tables;
     2 shop
     3 stu
     4 system.indexes
     5 > 
     6 > 
     7 > db.tea.insert({email:'a@163.com'})
     8 > db.tea.insert({email:'b@163.com'})
     9 > 
    10 > db.tea.getIndexes();
    11 [
    12 {
    13 "v" : 1,
    14 "key" : {
    15 "_id" : 1
    16 },
    17 "ns" : "test.tea",
    18 "name" : "_id_"
    19 }
    20 ]
    21 > 
    22 > 
    23 > 
    24 > db.tea.ensureIndex({email:1},{unique:true});
    25 > 
    26 > 
    27 > db.tea.insert({email:'c@163.com'})
    28 > db.tea.insert({email:'c@163.com'})
    29 E11000 duplicate key error index: test.tea.$email_1 dup key: { : "c@163.com" }
    30 >

     

    四. 稀疏索引

    稀疏索引的特点------如果针对field做索引,针对不含field列的文档,将不建立索引.
    与之相对,普通索引,会把该文档的field列的值认为NULL,并建索引.
    适宜于: 小部分文档含有某列时.

    db.collection.ensureIndex({field:1/-1},{sparse:true})

     

     1 -- 模拟数据
     2 > db.tea.insert({});
     3 > db.tea.find();
     4 { "_id" : ObjectId("5743d98aaddef29711337fb4"), "email" : "a@163.com" }
     5 { "_id" : ObjectId("5743d98daddef29711337fb5"), "email" : "b@163.com" }
     6 { "_id" : ObjectId("5743d9cfaddef29711337fb7"), "email" : "c@163.com" }
     7 { "_id" : ObjectId("5743dc98addef29711337fbc") }
     8 
     9  
    10 
    11 --稀疏索引下查不到数据
    12 > db.tea.ensureIndex({email:1},{sparse:true});
    13 > db.tea.find({email:null});
    14 >
    15 
    16 > db.tea.dropIndexes();
    17 {
    18 "nIndexesWas" : 2,
    19 "msg" : "non-_id indexes dropped for collection",
    20 "ok" : 1
    21 }
    22 
    23 --普通索引能查到
    24 > db.tea.ensureIndex({email:1});
    25 > db.tea.find({email:null});
    26 { "_id" : ObjectId("5743dc98addef29711337fbc") }

     总结:
    如果分别加普通索引,和稀疏索引,
    对于最后一行的email分别当成null 和 忽略最后一行来处理.
    根据{email:null}来查询,前者能查到,而稀疏索引查不到最后一行.

    五. 创建哈希索引(2.4新增的)

    哈希索引速度比普通索引快,但是,无能对范围查询进行优化.
    适宜于---随机性强的散列

    db.collection.ensureIndex({file:'hashed'});

     1 > db.tea.ensureIndex({email:'hashed'});
     2 > db.tea.find({email:'a@163.com'}).explain();
     3 {
     4 "cursor" : "BtreeCursor email_hashed",
     5 "isMultiKey" : false,
     6 "n" : 1,
     7 "nscannedObjects" : 1,
     8 "nscanned" : 1,
     9 "nscannedObjectsAllPlans" : 1,
    10 "nscannedAllPlans" : 1,
    11 "scanAndOrder" : false,
    12 "indexOnly" : false,
    13 "nYields" : 0,
    14 "nChunkSkips" : 0,
    15 "millis" : 0,
    16 "indexBounds" : {
    17 "email" : [
    18 [
    19 NumberLong("2069420833715827975"),
    20 NumberLong("2069420833715827975")
    21 ]
    22 ]
    23 },
    24 "server" : "localhost.localdomain:27017"
    25 }
    26 >

     

    六. 重建索引

    一个表经过很多次修改后,导致表的文件产生空洞,索引文件也如此.
    可以通过索引的重建,减少索引文件碎片,并提高索引的效率.
    类似mysql中的optimize table

    db.collection.reIndex()

     1 > db.tea.reIndex();
     2 {
     3 "nIndexesWas" : 2,
     4 "msg" : "indexes dropped for collection",
     5 "nIndexes" : 2,
     6 "indexes" : [
     7 {
     8 "key" : {
     9 "_id" : 1
    10 },
    11 "ns" : "test.tea",
    12 "name" : "_id_"
    13 },
    14 {
    15 "key" : {
    16 "email" : "hashed"
    17 },
    18 "ns" : "test.tea",
    19 "name" : "email_hashed"
    20 }
    21 ],
    22 "ok" : 1
    23 }
  • 相关阅读:
    JavaScript函数节流与函数去抖
    [概念] js的函数节流和throttle和debounce详解
    进度3_家庭记账本App_Fragment使用SQLite实现简单存储及查询
    网格视图GridView
    SQLite数据库以及增删改查的案例
    进度2_家庭记账本App
    进度1_家庭记账本App
    家庭记账本初步构想
    WebView的学习
    App基本界面组件案例
  • 原文地址:https://www.cnblogs.com/chinesern/p/5523057.html
Copyright © 2011-2022 走看看