索引中的小坑
通过实际开发和性能对比,总结了几条不用索引的情况:
- 数据不超万条时,不需要使用索引。性能的提升并不明显,而大大增加了内存和硬盘的消耗。
- 查询数据超过表数据量30%时,不要使用索引字段查询。实际证明会比不使用索引更慢,因为它大量检索了索引表和我们原表。
- 数字索引,要比字符串索引快的多,在百万级甚至千万级数据量面前,使用数字索引是个明智的选择。
- 把你经常查询的数据做成一个内嵌数据(对象型的数据),然后集体进行索引。
复合索引
复合索引就是两条以上的索引,之前我们已经把username字段建立了索引,我们现在把randNum0这个字段也设置成索引。
db.randInfo.ensureIndex({randNum0:1})
建立好后,我们再用查询索引状态命令进行查询。
db.randInfo.getIndexes()
这时候已经是两个自建索引了,一共有三个索引。
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "company.randInfo"
},
{
"v" : 2,
"key" : {
"username" : 1
},
"name" : "username_1",
"ns" : "company.randInfo"
},
{
"v" : 2,
"key" : {
"randNum0" : 1
},
"name" : "randNum0_1",
"ns" : "company.randInfo"
}
]
两个索引同时查询
我们同时查询两个索引的值,看看效果是怎么样的。
var startTime=new Date().getTime();
var db = connect('company');
var rs= db.randInfo.find({username:'gu7v2dtb',randNum0:565509});
rs.forEach(rs=>{printjson(rs)});
var runTime = new Date().getTime()-startTime;
print('[Demo]this run time is '+runTime+'ms');
从性能上看并没有什么特殊的变化,查询时间还是在4ms左右。MongoDB的复合查询是按照我们的索引顺序进行查询的。就是我们用db.randInfo.getIndexes()查询出的数组。
指定索引查询(hint)
数字的索引要比字符串的索引快,这就需要一个方法来打破索引表的查询顺序,用我们自己指定的索引优先查询,这个方法就是hint().
var rs= db.randInfo.find({username:'gu7v2dtb',randNum0:565509}).hint({randNum0:1});
由于数据量和复杂成都还是不大,所以看不出来明显的性能提升,等工作中遇到大数据时,一定会得到很好的效果的。
删除索引
当索引性能不佳或起不到作用时,我们需要删除索引,删除索引的命令是dropIndex().
db.randInfo.dropIndex('randNum0_1') //索引的唯一ID
这里需要注意的是删除时填写的值,并不是我们的字段名称(key),而是我们索引查询表中的name值。