内存分配与查询效率

当document被创建的时候DB为其分配内存和预留内存,当修改操作不超过预留内层的时候则速度非常快反而超过了就要分配新的内存则会消耗时间。

一、索引

MongoDB 提供了多样性的索引支持,索引信息被保存在system.indexes 中,且默认总是为_id创建索引,它的索引使用基本和MySQL 等关系型数据库一样。其实可以这样说说,索引是凌驾于数据存储系统之上的另一层系统,所以各种结构迥异的存储都有相同或相似的索引实现及使用接口并不足为奇。

1.1、MongoDB索引类型

MongoDB支持多种类型的索引,包括单字段索引、复合索引、多key索引、文本索引等,每种类型的索引有不同的使用场合。

单字段索引 (Single Field Index)

db.person.createIndex( {age: 1} ) 

上述语句针对age创建了单字段索引,其能加速对age字段的各种查询请求,是最常见的索引形式,MongoDB默认创建的id索引也是这种类型。

{age: 1} 代表升序索引,也可以通过{age: -1}来指定降序索引,对于单字段索引,升序/降序效果是一样的。

复合索引 (Compound Index)

复合索引是Single Field Index的升级版本,它针对多个字段联合创建索引,先按第一个字段排序,第一个字段相同的文档按第二个字段排序,依次类推,如下针对age, name这2个字段创建一个复合索引。

db.person.createIndex( {age: 1, name: 1} ) 

复合索引能满足的查询场景比单字段索引更丰富,不光能满足多个字段组合起来的查询,比如db.person.find( {age: 18, name: "jack"} ),也能满足所以能匹配符合索引前缀的查询,这里{age: 1}即为{age: 1, name: 1}的前缀,所以类似db.person.find( {age: 18} )的查询也能通过该索引来加速;但db.person.find( {name: "jack"} )则无法使用该复合索引。如果经常需要根据『name字段』以及『name和age字段组合』来查询,则应该创建如下的复合索引

db.person.createIndex( {name: 1, age: 1} ) 

除了查询的需求能够影响索引的顺序,字段的值分布也是一个重要的考量因素,即使person集合所有的查询都是『name和age字段组合』(指定特定的name和age),字段的顺序也是有影响的。

age字段的取值很有限,即拥有相同age字段的文档会有很多;而name字段的取值则丰富很多,拥有相同name字段的文档很少;显然先按name字段查找,再在相同name的文档里查找age字段更为高效。

多key索引 (Multikey Index)

当索引的字段为数组时,创建出的索引称为多key索引,多key索引会为数组的每个元素建立一条索引,比如person表加入一个habbit字段(数组)用于描述兴趣爱好,需要查询有相同兴趣爱好的人就可以利用habbit字段的多key索引。

{"name" : "jack", "age" : 19, habbit: ["football, runnning"]}
db.person.createIndex( {habbit: 1} ) // 自动创建多key索引
db.person.find( {habbit: "football"} )

其他类型索引

哈希索引(Hashed Index)是指按照某个字段的hash值来建立索引,目前主要用于MongoDB Sharded Cluster的Hash分片,hash索引只能满足字段完全匹配的查询,不能满足范围查询等。

地理位置索引(Geospatial Index)能很好的解决O2O的应用场景,比如『查找附近的美食』、『查找某个区域内的车站』等。

文本索引(Text Index)能解决快速文本查找的需求,比如有一个博客文章集合,需要根据博客的内容来快速查找,则可以针对博客内容建立文本索引。

索引额外属性

MongoDB除了支持多种不同类型的索引,还能对索引定制一些特殊的属性。

  • 唯一索引 (unique index):保证索引对应的字段不会出现相同的值,比如_id索引就是唯一索引
  • TTL索引:可以针对某个时间字段,指定文档的过期时间(经过指定时间后过期 或 在某个时间点过期)
  • 部分索引 (partial index): 只针对符合某个特定条件的文档建立索引,3.2版本才支持该特性
  • 稀疏索引(sparse index): 只针对存在索引字段的文档建立索引,可看做是部分索引的一种特殊情况

1.2、createIndex() 方法

MongoDB使用 createIndex() 方法来创建索引。

注意在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex(),之后的版本使用了 db.collection.createIndex() 方法,ensureIndex() 还能用,但只是 createIndex() 的别名。

1.为普通字段添加索引,并且为索引命名

db.集合名.createIndex(待创建索引的列 [,额外选项])

说明: (1)索引命名规范:idx_<构成索引的字段名>。如果字段名字过长,可采用字段缩写。

         (2)字段值后面的 1 代表升序;如是 -1 代表 降序。

示例:

db.t_order.createIndex({"order_no":-1},{unique:true,name:"idx_order_no"});

2.为内嵌字段添加索引

db.集合名.createIndex({"字段名.内嵌字段名":1},{"name":'idx_字段名_内嵌字段名'})

3.通过后台创建索引

db.集合名.createIndex({"字段名":1},{"name":'idx_字段名',background:true})

4:组合索引

db.集合名.createIndex({"字段名1":-1,"字段名2":1},{"name":'idx_字段名1_字段名2',background:true})

5.设置TTL 索引

db.集合名.createIndex( { "字段名": 1 },{ "name":'idx_字段名',expireAfterSeconds: 定义的时间,background:true} )

说明 :expireAfterSeconds为过期时间(单位秒)

6.createIndex() 接收可选参数汇总

Parameter Typ Description
background Boolean 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false
unique Boolean 建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
name string 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
sparse Boolean 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false.
expireAfterSeconds integer 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
weights document 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
default_language string 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语

1.2、查看索引

MongoDB提供了查看索引信息的方法:getIndexes()方法可以用来查看集合的所有索引,totalIndexSize()查看集合索引的总大小,db.system.indexes.find()查看数据库中所有索引信息。

查看集合中的索引getIndexes()

db.COLLECTION_NAME.getIndexes()

如,查看集合sites中的索引:

>db.sites.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "newDB.sites"
},
{
"v" : 1,
"key" : {
"name" : 1,
"domain" : -1
},
"name" : "name_1_domain_-1",
"ns" : "newDB.sites"
}
]

查看集合中的索引大小totalIndexSize()

db.COLLECTION_NAME.totalIndexSize()

如,查看集合sites索引大小:

> db.sites.totalIndexSize()
16352

查看数据库中所有索引db.system.indexes.find()

db.system.indexes.find()

如,当前数据库的所有索引:

> db.system.indexes.find()

1.3、删除索引

不在需要的索引,我们可以将其删除。删除索引时,可以删除集合中的某一索引,可以删除全部索引。

3.1 删除指定的索引dropIndex()

db.COLLECTION_NAME.dropIndex("INDEX-NAME")

如,删除集合sites中名为"name_1_domain_-1"的索引:

> db.sites.dropIndex("name_1_domain_-1")
{ "nIndexesWas" : 2, "ok" : 1 }

3.3 删除所有索引dropIndexes()

db.COLLECTION_NAME.dropIndexes()

如,删除集合sites中所有的索引:

> db.sites.dropIndexes()
{
"nIndexesWas" : 1,
"msg" : "non-_id indexes dropped for collection",
"ok" : 1
}

1.基础索引

在字段age 上创建索引,1(升序);-1(降序):

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

_id 是创建表的时候自动创建的索引,此索引是不能够删除的。当系统已有大量数据时,创建索引就是个非常耗时的活,我们可以在后台执行,只需指定“backgroud:true”即可。

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

2.文档索引

索引可以任何类型的字段,甚至文档:

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

//在addr 列上创建索引

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

//下面这个查询将会用到我们刚刚建立的索引

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

//但是下面这个查询将不会用到索引,因为查询的顺序跟索引建立的顺序不一样

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

3. 组合索引

跟其它数据库产品一样,MongoDB 也是有组合索引的,下面我们将在addr.city 和addr.state上建立组合索引。当创建组合索引时,字段后面的1 表示升序,-1 表示降序,是用1 还是用-1 主要是跟排序的时候或指定范围内查询 的时候有关的。

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

// 下面的查询都用到了这个索引

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 } );

4. 唯一索引

只需在ensureIndex 命令中指定”unique:true”即可创建唯一索引。例如,往表t4 中插入2 条记录时候报错。

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

5.强制使用索引

hint 命令可以强制使用某个索引。

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

6.删除索引

//删除t3 表中的所有索引

db.t3.dropIndexes()

//删除t4 表中的firstname 索引

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

CXF之六 自定义拦截器的更多相关文章

  1. (六)CXF之自定义拦截器

    一.需求分析 客户端在调用服务端的方法时,需要进行用户名和密码验证.此时分为: 客户端请求的时候,要发送用户名密码到服务端 服务端检验用户名密码. 二.案例 前提:本章案例是基于前一章节的例子进一步讲 ...

  2. Apache CXF自定义拦截器

    为什么设计拦截器?1.为了在webservice请求过程中,能动态操作请求和响应数据,CXF设计了拦截器 拦截器分类: 1.按所处的位置分:服务器端拦截器,客户端拦截器. 2.按消息的方向分:入拦截器 ...

  3. CXF添加拦截器和自定义拦截器

    前面讲了如何采用CXF开发webservice,现在来讲如何添加拦截器和自定义拦截器. 服务端代码: HelloWorld implementor=new HelloWorldImpl(); Stri ...

  4. spring mvc <mvc:annotation-driven/> 自定义拦截器不走

    <mvc:annotation-driven/> 这个便签会注册2个自定义拦截器,所以导致请求过来就会自己去走注册的这2个拦截器和定义的一堆bean 但是这个便签是必须得定义的 直接贴代码 ...

  5. 12.Struts2自定义拦截器

    12.自定义拦截器        拦截器是Struts2的一个重要特性.因为Struts2的大多数核心功能都是通过拦截器实现的. 拦截器之所以称之为“拦截器”,是因为它可以拦截Action方法的执行, ...

  6. 【Java EE 学习 35 下】【struts2】【struts2文件上传】【struts2自定义拦截器】【struts2手动验证】

    一.struts2文件上传 1.上传文件的时候要求必须使得表单的enctype属性设置为multipart/form-data,把它的method属性设置为post 2.上传单个文件的时候需要在Act ...

  7. SpringMVC——自定义拦截器、异常处理以及父子容器配置

    自定义拦截器: 一.若想实现自定义拦截器,需要实现 org.springframework.web.servlet.HandlerInterceptor 接口. 二.HandlerIntercepto ...

  8. Struts2 自定义拦截器

    自定义拦截器(权限管理),包含了对ajax和表单请求的拦截 package com.interceptor; import java.io.IOException; import java.io.Pr ...

  9. Struts2自定义拦截器

    1. 需求 自定义拦截器实现,用户登录的访问控制. 2. 定义拦截器类 public class LoginInterceptor extends AbstractInterceptor { @Ove ...

随机推荐

  1. qsort()与besearch()

    功 能: 使用快速排序例程进行排序 头文件:stdlib.h 用 法: void qsort(void *base,int nelem,int width,int (*fcmp)(const void ...

  2. 玩转图片Base64编码

    什么是 base64 编码? 图片的 base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址. 这样做有什么意义呢?我们知道,我们所看到的网页上的每一个图片,都是需要消耗一 ...

  3. 天气API整理,返回的数据格式为json对象

    中国天气的API惨遭封杀,不得已更换其他的API使用吧. 这里大部分API来自APP的数据包截取或者反汇编,所以各开发使用者不得用于商业用途,否则后果自负! 1.金山网址导航 来源:http://ww ...

  4. Linux和Linux之间共享目录

    1.Linux 服务器端NFS服务器的配置 以root身份登陆Linux服务器,编辑/etc目录下的共享目录配置文件exports,指定共享目录及权限等. 执行如下命令编辑文件/etc/exports ...

  5. Rebound-Android的弹簧动画库

    Rebound是facebook出品的一个弹簧动画库,与之对应的IOS版本有一个pop动画库,也是非常的强大给力.Facebook真是互联网企业中的楷模,开源了很多的实用开源库,大赞一个!!! 讲解R ...

  6. ZipArchive框架的文件压缩和解压

    导入第三方框架ZipArchive之后还要在系统库文件中导入一个如下文件(搜索libz出来的任何一个都可以)   导入的头文件是#import "Main.h" 文件压缩 -(vo ...

  7. 在对话框上拖动按钮并移动该按钮(改写CXXButton::PreTranslateMessage,然后MoveWindow)

    // 派生自CButton类,主要过滤WM_LBUTTONDOWN .WM_LBUTTONUP和WM_MOUSEMOVE消息. BOOL m_bFlag = FALSE; // 成员变量,用来标示鼠标 ...

  8. iOS Objective-C对象模型及应用

    前言 原创文章,转载请注明出自唐巧的技术博客. 本文主要介绍Objective-C对象模型的实现细节,以及Objective-C语言对象模型中对isa swizzling和method swizzli ...

  9. [iOS]开发者证书和描述文件的作用

    先说下证书吧. 然后是描述文件

  10. NSRange

    int main(int argc, const char * argv[]) {    @autoreleasepool {        // insert code here...       ...