MongoDB 索引
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文档并选取那些符合查询条件的记录。
这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构
语法:
ensureIndex()方法基本语法格式如下所示:
>db.COLLECTION_NAME.ensureIndex({KEY:1})
语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,-1即为降序。
explain命令
MongoDB 提供了一个 explain 命令让我们获知系统如何处理查询请求。利用 explain 命令,可以很好地观察系统如何使用索引来加快检索,同时可以针对性优化索引。
实例
1. 构建数据
db.inventory.insert([
{ "_id" : 1, "item" : "f1", type: "food", quantity: 500 },
{ "_id" : 2, "item" : "f2", type: "food", quantity: 100 },
{ "_id" : 3, "item" : "p1", type: "paper", quantity: 200 },
{ "_id" : 4, "item" : "p2", type: "paper", quantity: 150 },
{ "_id" : 5, "item" : "f3", type: "food", quantity: 300 },
{ "_id" : 6, "item" : "t1", type: "toys", quantity: 500 },
{ "_id" : 7, "item" : "a1", type: "apparel", quantity: 250 },
{ "_id" : 8, "item" : "a2", type: "apparel", quantity: 400 },
{ "_id" : 9, "item" : "t2", type: "toys", quantity: 50 },
{ "_id" : 10, "item" : "f4", type: "food", quantity: 75 }])
2. 无索引查询
db.inventory.find(
{
quantity: {
$gte: 100,
$lte: 200
}
}
).explain("executionStats")
- COLLSCAN
如果你仔细一看,知道是CollectionScan,就是所谓的“集合扫描”,看到集合扫描 相当于 sql数据库中的table scan
- nReturned
就是所谓的numReturned,就是说最后返回的num个数,从图中可以看到,就是最终返回了三条。。。
- docsExamined
就是documentsExamined
,检查了10个documents。。。而从返回上面的nReturned。。。
从上面三个信息中得出,docsExamined
10条数据,最终才返回nReturned
3条,说明做了7条数据scan的无用功,那么这个时候问题就来了!!!
3. 创建索引
知道前因后果之后,我们就可以进行针对性的建立索引,比如在quality字段之上,如下:
db.inventory.createIndex({ quantity: 1})
db.inventory.find(
{ quantity: { $gte: 100, $lte: 200 } }
).explain("executionStats")
好了,这时候就有意思了,当我们执行完createindex之后,再次explain,4个重要的parameters就漂下来了:
- IXSCAN
这个时候再也不是所谓的COLLSCAN了,而是IndexScan,这就说明我们已经命中索引了。
- nReturned, totalDocsExamined, totalKeysExamined
从图中可以看到三个参数都是3,这就说明我们的mongodb查看了3个key,3个document,返回3个文档,这个就是所谓的高性能所在,对吧。
3. 查看索引
getindexes可以查看索引,
db.inventory.getIndexes()
4. 索引
代价
索引会增加写操作的代价
收益
查询效率高
索引 在MongoDB Schema 和 SQL Schema 区别
SQL Schema Statements | MongoDB Schema Statements |
---|---|
CREATE INDEX idx_user_id_asc
ON users(user_id)
|
db.users.createIndex( { user_id: 1 } )
|
CREATE INDEX
idx_user_id_asc_age_desc
ON users(user_id, age DESC)
|
db.users.createIndex( { user_id: 1, age: -1 } )
|