引子
索引是提高性能的关键
简介
在目录缺失的情况下,如何在很厚的一本书中快速找到指定的章节?
数据库的索引和书籍的目录类似
示例
创建一个1000000的文档集合:
> for (i=0;i<1000000;i++) {
... db.machine.insert({
... "machineName":"测试机械00" + i,
... "fenceName":"测试机械围栏00" + i,
... "remark":"测试机械备注00" + i,
... "created_at":new Date()
... });
... }
WriteResult({ "nInserted" : 1 })
查询指定的某一条数据,并查看花费的时间:
> db.machine.find({"machineName":"测试机械00999"}).explain("executionStats").executionStats.executionTimeMillis
1228
查看同样的一条数据,查看其文档扫描数:
> db.machine.find({"machineName":"测试机械00999"}).explain("executionStats").executionStats.totalDocsExamined
1000099
根据上面的查询返回参数可得出结论:
1、查询执行时间为1228毫秒
2、查询扫描文档数为1000099个(全部)
这时候优化一下查询,添加一个limit()参数后,时间花费:
> db.machine.find({"machineName":"测试机械00999"}).limit(1).explain("executionStats").executionStats.executionTimeMillis
1
文档扫描数为:
> db.machine.find({"machineName":"测试机械00999"}).limit(1).explain("executionStats").executionStats.totalDocsExamined
1099
根据返回参数可以得到结论:
1、查询执行时间为1毫秒
2、查询扫描文档数为1099个
因为只查询一条数据,在遍历查询时查到一条数据就立即返回,所以耗时很少。
如果想查询的数据很靠后呢,依旧会扫描很多文档,花费更多的时间才会查询到。
创建索引
> db.machine.ensureIndex({"machineName":1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
然后重新执行一下上面的查询以及时间花费为:
> db.machine.find({"machineName":"测试机械00999"}).explain("executionStats").executionStats.executionTimeMillis
1
文档扫描数为:
> db.machine.find({"machineName":"测试机械00999"}).explain("executionStats").executionStats.totalDocsExamined
1
根据返回参数可以得到结论:
1、查询执行时间为1毫秒
2、查询扫描文档数为1个
可以看出,有了索引查询几乎瞬间完成。
问题
1、每次写操作(插入、更新、删除)要花费更多的时间
2、添加索引会占用更多物理空间
网友评论