欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【赵强老师】MongoDB中的索引(上)

程序员文章站 2022-03-05 20:25:34
...

【赵强老师】MongoDB中的索引(上)
            
    
    博客分类: 大数据OracleSQLNoSQLMongoDBRedisHadoop 大数据OracleSQLNoSQLMongoDB

索引是提高查询查询效率最有效的手段。索引是一种特殊的数据结构,索引以易于遍历的形式存储了数据的部分内容(如:一个特定的字段或一组字段值),索引会按一定规则对存储值进行排序,而且索引的存储位置在内存中,所在从索引中检索数据会非常快。如果没有索引,MongoDB必须扫描集合中的每一个文档,这种扫描的效率非常低,尤其是在数据量较大时。

一、索引的基础知识

下面以关系型数据库Oracle为例,介绍索引的基本原理,如下图所示:

【赵强老师】MongoDB中的索引(上)
            
    
    博客分类: 大数据OracleSQLNoSQLMongoDBRedisHadoop 大数据OracleSQLNoSQLMongoDB

从上图可以看成,索引的本质其实就相当于是一本书的目录。当查询表中数据的时候,先查询目录(索引)中的行地址,再通过行地址查询到表中的数据,从而提高查询的性能。

下图说明了在MongoDB中,索引在查询和排序中是如何工作的?

【赵强老师】MongoDB中的索引(上)
            
    
    博客分类: 大数据OracleSQLNoSQLMongoDBRedisHadoop 大数据OracleSQLNoSQLMongoDB

通过这个例子,可以清楚的看到索引存储的是一个特定字段或者几个字段的集合,并且按照一定的规律排序。当创建集合的时候,MongoDB自动在_id上创建一个唯一性索引,由于是唯一性的,所以可以防止重复的_id值插入到集合中。通过getIndexes可以查询到MongoDB集合上的索引信息,如下图所示。

【赵强老师】MongoDB中的索引(上)
            
    
    博客分类: 大数据OracleSQLNoSQLMongoDBRedisHadoop 大数据OracleSQLNoSQLMongoDB

当没有索引的时候,通过查看执行计划,可以看到查询的过程,如下:查询:10号部门,工资小于3000的文档。

【赵强老师】MongoDB中的索引(上)
            
    
    博客分类: 大数据OracleSQLNoSQLMongoDBRedisHadoop 大数据OracleSQLNoSQLMongoDB

那么如何创建一个简单的索引呢?注意从mongoDB 3.0开始ensureIndex被废弃,今后都仅仅是db.collection.createIndex的一个别名。

【赵强老师】MongoDB中的索引(上)
            
    
    博客分类: 大数据OracleSQLNoSQLMongoDBRedisHadoop 大数据OracleSQLNoSQLMongoDB

现在在deptno和sal上建立一个索引,并重新查看执行计划:db.emp.createIndex({"deptno":1,"sal":-1})

【赵强老师】MongoDB中的索引(上)
            
    
    博客分类: 大数据OracleSQLNoSQLMongoDBRedisHadoop 大数据OracleSQLNoSQLMongoDB

注意:除了可以使用explain()生成执行计划外,还可以有几个可选的参数,如下:
.explain("allPlansExecution")
.explain("executionStats")
.explain("queryPlanner")

二、索引的类型一:单键索引(Single Field)

单键索引是最普通的索引,与_id索引不同,单键索引不会自动创建。

准备数据:
db.testindex1.insert({"_id":1,"zipcode":1034,"location":{state:"NY",city:"New York"}})

在单个列上创建单键索引:
db.testindex1.createIndex({"zipcode":1})

在嵌套的列上创建单键索引
db.testindex1.createIndex({"location:state":1})

在内嵌的文档上创建单键索引
db.testindex1.createIndex({"location":-1})
这样将会把location作为一个整体。

三、索引的类型二:多键索引(Multikey Index)

多键索引与单键索引创建形式相同,区别在于字段的值。值具有多个记录,如数组。

【赵强老师】MongoDB中的索引(上)
            
    
    博客分类: 大数据OracleSQLNoSQLMongoDBRedisHadoop 大数据OracleSQLNoSQLMongoDB

如上图,基于集合上的数组创建多键索引,且数组为内嵌文档。

准备数据:
db.testindex2.insertMany([
{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9 ] },
{ _id: 6, type: "food", item: "bbb", ratings: [ 5, 9 ] },
{ _id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8 ] },
{ _id: 8, type: "food", item: "ddd", ratings: [ 9, 5 ] },
{ _id: 9, type: "food", item: "eee", ratings: [ 5, 9, 5 ] }])

下面基于ratings列创建一个多键索引:
db.testindex2.createIndex( { ratings: 1 } )

查询数组上为5,9的文档
db.testindex2.find( { ratings: [ 5, 9 ] } )

下面查看其执行计划
db.testindex2.find( { ratings: [ 5, 9 ] } ).explain()

【赵强老师】MongoDB中的索引(上)
            
    
    博客分类: 大数据OracleSQLNoSQLMongoDBRedisHadoop 大数据OracleSQLNoSQLMongoDB

【赵强老师】MongoDB中的索引(上)
            
    
    博客分类: 大数据OracleSQLNoSQLMongoDBRedisHadoop 大数据OracleSQLNoSQLMongoDB