1. 程式人生 > >關於給mongodb集合中的某些欄位新增索引

關於給mongodb集合中的某些欄位新增索引

    我們知道mongodb是一種文字資料庫,它和mysql資料庫一樣,都存在索引這一概念。給欄位新增索引,可以加快資料查詢的速度。當然了,在資料量足夠大的情況下,加索引和不加索引的差距是很明顯的。但是加了索引之後,在儲存方面大概是會很浪費時間的。

1、單一索引

    mongodb中使用以下命令來給欄位新增索引。現在先簡單的介紹一下,專案中用到的兩種單一索引、集合索引。首先在mongodb中新增一個users集合:

> for(var i=0;i<100000;i++){ db.users.insert({username:'user'+i}) }
WriteResult({ "nInserted" : 1 })

檢視該集合中存在哪些索引:

> db.users.getIndexes()
[
	{
		"v" : 2,
		"key" : {
			"_id" : 1
		},
		"name" : "_id_",
		"ns" : "test.users"
	}
]

我們先來看一下查詢user99999需要用多長的時間:我們可以看到"executionTimeMillis" : 50,也就是查詢這一條記錄,一共需要遍歷"totalDocsExamined" : 100200,消耗了50毫秒。

> db.users.find({"username":"user99999"}).explain("executionStats")
{
	"queryPlanner" : {
		"plannerVersion" : 1,
		"namespace" : "test.users",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"username" : {
				"$eq" : "user99999"
			}
		},
		"winningPlan" : {
			"stage" : "COLLSCAN",
			"filter" : {
				"username" : {
					"$eq" : "user99999"
				}
			},
			"direction" : "forward"
		},
		"rejectedPlans" : [ ]
	},
	"executionStats" : {
		"executionSuccess" : true,
		"nReturned" : 1,
		"executionTimeMillis" : 50,
		"totalKeysExamined" : 0,
		"totalDocsExamined" : 100200,
		"executionStages" : {
			"stage" : "COLLSCAN",
			"filter" : {
				"username" : {
					"$eq" : "user99999"
				}
			},
			"nReturned" : 1,
			"executionTimeMillisEstimate" : 46,
			"works" : 100202,
			"advanced" : 1,
			"needTime" : 100200,
			"needYield" : 0,
			"saveState" : 783,
			"restoreState" : 783,
			"isEOF" : 1,
			"invalidates" : 0,
			"direction" : "forward",
			"docsExamined" : 100200
		}
	},
	"serverInfo" : {
		"host" : "guolujiedeMacBook-Pro.local",
		"port" : 27017,
		"version" : "4.0.2",
		"gitVersion" : "fc1573ba18aee42f97a3bb13b67af7d837826b47"
	},
	"ok" : 1
}

我們現在給該集合的username加上索引,現在有兩個索引:

> db.users.createIndex({"username":1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}
> db.users.getIndexes()
[
	{
		"v" : 2,
		"key" : {
			"_id" : 1
		},
		"name" : "_id_",
		"ns" : "test.users"
	},
	{
		"v" : 2,
		"key" : {
			"username" : 1
		},
		"name" : "username_1",
		"ns" : "test.users"
	}
]

我們再來查詢一下加上索引之後需要消耗的時間:竟然只用了2毫秒,只需要查詢一條記錄。是不是效率提高了很多。

"executionStats" : {
		"executionSuccess" : true,
		"nReturned" : 1,
		"executionTimeMillis" : 2,
		"totalKeysExamined" : 1,
		"totalDocsExamined" : 1,
		"executionStages" : {
			"stage" : "FETCH",
			"nReturned" : 1,
			"executionTimeMillisEstimate" : 0,
			"works" : 2,
			"advanced" : 1,
			"needTime" : 0,
			"needYield" : 0,
			"saveState" : 0,
			"restoreState" : 0,
			"isEOF" : 1,
			"invalidates" : 0,
			"docsExamined" : 1,
			"alreadyHasObj" : 0,
			"inputStage" : {
				"stage" : "IXSCAN",
				"nReturned" : 1,
				"executionTimeMillisEstimate" : 0,
				"works" : 2,
				"advanced" : 1,
				"needTime" : 0,
				"needYield" : 0,
				"saveState" : 0,
				"restoreState" : 0,
				"isEOF" : 1,
				"invalidates" : 0,
				"keyPattern" : {
					"username" : 1
				},
				"indexName" : "username_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"username" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"username" : [
						"[\"user99999\", \"user99999\"]"
					]
				},
				"keysExamined" : 1,
				"seeks" : 1,
				"dupsTested" : 0,
				"dupsDropped" : 0,
				"seenInvalidated" : 0
			}
		}
	},

2、聯合索引

    聯合索引的新增方法如下:

> db.students.createIndex({"stuId":1,"name":1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}
> db.students.getIndexes()
[
	{
		"v" : 2,
		"key" : {
			"_id" : 1
		},
		"name" : "_id_",
		"ns" : "test.students"
	},
	{
		"v" : 2,
		"key" : {
			"stuId" : 1,
			"name" : 1
		},
		"name" : "stuId_1_name_1",
		"ns" : "test.students"
	}
]

    刪除指定索引的方法如下:

> db.students.dropIndex("stuId_1_name_1")
{ "nIndexesWas" : 2, "ok" : 1 }

    刪除所有索引的方法如下:

> db.students.dropIndexes()
{
	"nIndexesWas" : 1,
	"msg" : "non-_id indexes dropped for collection",
	"ok" : 1
}