目前所使用的对于MongoDB数据库的操作仅限于插入和查询,以td_patient_da这个collection为例:
需求:获取大量数据里面抽烟的人的数量
1.结构,
td_patient_da是一个问卷调查的表格。
从数据来源上看,td_patient_da这个存储的数据包括两个部分,1.表体本身的数据2.用户所填的数据 这两个数据都会放在td_patient_da集合
里面。各司其职,真正要统计的是用户填的数据,表体数据相当于java里面的引用,指向用户填的数据,便于统计的时候获取对应的数据。
要做的是合理利用表体结构准确,高效的获取所需数据。
表体结构分析:td_patient_da总共有5层
2.MongoDB查询实现
db.td_patient_da.find({"busiJson.4.formid":"7f3d37af8773486a9fc96607821036e4","busiJson.4.data.1.value":"146131089757712GP▄现在吸"}).count()
db.td_patient_da.find({"busiJson.4.formid":"7f3d37af8773486a9fc96607821036e4","busiJson.4.data.6.value":"1461311077354PUIW▄近1年不饮"}).count()
3.java实现
查询:
插入:
4.现象及结果分析:
这样是可以达到预期效果的,但是一旦数据量达到很大,十万条,五十万条,便没法获取结果了
5.改进措施引入索引
1)创建组合索引
db.td_patient_da.ensureIndex( {"busiJson.4.data.1.value":1} )
db.td_patient_da.ensureIndex( {"busiJson.4.formid":1,"busiJson.4.data.1.value":1} )
经测试发现,创建此索引对于该busiJson.4.formid&&busiJson.4.data.1.value实现秒出。
但是如果创建的是组合索引,却只用一个查询条件查询的情况
只对主索引进行busiJson.4.formid 查询很快,只对副索引查询busiJson.4.data.1.value查询很慢,
2) 非索引查询
在服务器上测试:如果一边在插数据,一边进行查询,效率会变慢
10W数据 只查询 建索引 64秒 非索引查询(单条件):11秒 非索引查询(2条件) 52秒
20W数据 只查询 建索引104秒 非索引查询(单条件):110秒 非索引查询(2条件) 112秒
50W数据 只查询 310 297
100W 740 715
正在向A数据库插入50W数据,对A库做查询:
10W数据 实时边插入边查询 建索引20秒 非索引查询(单条件) 30秒
20W数据 实时边插入边查询 建索引 非索引查询(单条件) 178 二条件查询 106秒
30W数据 实时边插入边查询 建索引 188 非索引查询(单条件) 192 二条件查询 182 (建索引会阻塞插入数据)
40W数据 实时边插入边查询 建索引 非索引查询(单条件) 254 二条件查询 182
50W数据 实时边插入边查询 建索引 非索引查询(单条件) 二条件查询
正在向A数据库插入50W数据,对B库进行查询:20W数据 非被实时插入表格:
边插入边查询 建索引122秒 非索引查询(单条件) 117秒 二条件 108秒
--index
默认索引_id,集合被创建的时候会自动生成
db.td_patient_da.ensureIndex( {"busiJson":1} ); ---单列索引
db.td_patient_da.ensureIndex( {"arrivalId":1,"busiJson":1} ); ---组合索引 主:arrivalId 副:busiJson 1表示升序 -1表示降序
db.td_patient_da.ensureIndex( {"busiJson.4.data.1.value":1} ) ---子文档索引
db.td_patient_da.getIndexes() ---查看所有索引
db.td_patient_da.totalIndexSize() ---查看所有索引的大小
db.td_patient_da.dropIndex('busiJson') ---删除索引
db.td_patient_da.dropIndex(‘*’) ---删除所有索引 _id不会被删除
测试:因为建好索引后查询速度是飞快的,这里不做测试
db.td_patient_da.find({"busiJson.6.formid":"5b1bba6ab78649dbbcd8c1e5ad9685cf"}).count()
----单条件查询
db.td_patient_da.find({"arrivalId":"5b374a8496dc4b9a9bead2794f598ce8","busiJson.4.data.1.value":"14613108975772N3R▄从没吸过"}).count()
--二条件查询
db.td_patient_da.ensureIndex( {"busiJson.4.data.1.value":1} ) --建索引