Chỉ mục một phần mongodb

Hãy xem xét bạn có một bảng rất lớn trong MySQL với một cột boolean. Thông thường, bạn đã tạo trường ENUM('T','F') để lưu trữ thông tin boolean hoặc cột TINYINT để chỉ lưu trữ các số 1 và 0. Điều này là tốt cho đến nay. Nhưng bây giờ hãy nghĩ xem bạn có thể làm gì nếu bạn cần chạy nhiều truy vấn trên bảng, với một điều kiện trên trường boolean và không có điều kiện liên quan nào khác trên các cột được lập chỉ mục khác được sử dụng để lọc các hàng đã kiểm tra

Tại sao không tạo và lập chỉ mục trên trường boolean?

Hãy nghĩ xem liệu bạn có phân phối đồng đều các giá trị đúng và sai trong bảng hay không, ít nhiều là 50. chia 50. Trong tình huống này, không thể sử dụng chỉ mục trên cột boolean vì MySQL sẽ ưu tiên thực hiện quét toàn bộ bảng lớn thay vì chọn một nửa số hàng bằng cách sử dụng các mục nhập BTREE. Chúng ta có thể nói rằng một trường boolean như trường này có số lượng thẻ thấp và nó không có tính chọn lọc cao

Bây giờ hãy xem xét trường hợp bạn không có phân phối giá trị đồng đều, giả sử 2% số hàng chứa sai và 98% còn lại chứa đúng. Trong tình huống như vậy, một truy vấn để chọn các giá trị sai rất có thể sẽ sử dụng chỉ mục. Các truy vấn để chọn giá trị thực sẽ không sử dụng chỉ mục, vì lý do tương tự mà chúng ta đã thảo luận trước đây. Trong trường hợp thứ hai này, chỉ mục rất hữu ích, nhưng chỉ để chọn phần lớn các hàng. 98% mục còn lại trong chỉ mục hoàn toàn vô dụng. Điều này thể hiện sự lãng phí lớn về dung lượng đĩa và tài nguyên, bởi vì chỉ mục phải được duy trì cho mỗi lần ghi

Không chỉ các phép toán luận có thể gặp vấn đề này liên quan đến việc sử dụng chỉ mục, mà bất kỳ trường nào có số lượng thẻ thấp

Ghi chú. có một số cách giải quyết để giải quyết vấn đề này, tôi biết. Ví dụ: bạn có thể tạo một chỉ mục nhiều cột bằng cách sử dụng trường chọn lọc hơn và boolean. Hoặc bạn có thể thiết kế cơ sở dữ liệu của mình theo cách khác. Ở đây, tôi đang minh họa bản chất của vấn đề để giải thích tính năng MongoDB trong ngữ cảnh.  

Vấn đề boolean trong MongoDB

Làm thế nào về MongoDB? . vâng, MongoDB có cùng một vấn đề. Nếu bạn có nhiều tài liệu trong một bộ sưu tập có trường boolean hoặc trường lực lượng thấp và bạn tạo một chỉ mục trên đó, thì bạn sẽ có một chỉ mục rất lớn không thực sự hữu ích. Nhưng quan trọng hơn, bạn sẽ phải ghi xuống cấp để bảo trì chỉ mục

Sự khác biệt duy nhất là MongoDB sẽ có xu hướng sử dụng chỉ mục, thay vì thực hiện quét toàn bộ bộ sưu tập, nhưng thời gian thực hiện sẽ có cùng độ lớn như thực hiện COLLSCAN. Trong trường hợp các chỉ mục rất lớn, nên sử dụng COLLSCAN

May mắn thay, MongoDB có một tùy chọn mà bạn có thể chỉ định trong quá trình tạo chỉ mục để xác định Chỉ mục một phần. Hãy xem nào

Chỉ mục một phần

Chỉ mục một phần là chỉ mục chỉ chứa một tập hợp con các giá trị dựa trên quy tắc lọc. Vì vậy, trong trường hợp trường boolean được phân phối không đều, chúng ta có thể tạo một chỉ mục trên đó chỉ định rằng chúng ta chỉ muốn xem xét các giá trị sai. Bằng cách này, chúng tôi tránh ghi lại 98% mục nhập thực vô dụng còn lại. Chỉ mục sẽ nhỏ hơn, chúng tôi sẽ tiết kiệm dung lượng đĩa và bộ nhớ, đồng thời việc ghi thường xuyên nhất – khi nhập các giá trị thực – sẽ không bắt đầu hoạt động quản lý chỉ mục. Do đó, chúng tôi sẽ không bị phạt nhiều trong khi ghi nhưng chúng tôi sẽ có một chỉ mục hữu ích khi tìm kiếm các giá trị sai

Giả sử rằng, khi bạn có phân phối không đồng đều, các tìm kiếm phù hợp nhất là những tìm kiếm dành cho thiểu số các giá trị. Đây nói chung là kịch bản cho các ứng dụng thực tế

Bây giờ hãy xem cách tạo Chỉ mục một phần

Đầu tiên, hãy tạo một bộ sưu tập với một triệu tài liệu ngẫu nhiên. Mỗi tài liệu chứa một trường boolean được tạo bởi hàm javascript RandomBool(). Hàm tạo ra một giá trị sai trong 5% tài liệu, để phân phối không đồng đều. Sau đó, kiểm tra số lượng giá trị sai trong bộ sưu tập

Vỏ bọc

1

2

3

4

5

6

7

> chức năng randomBool() { var bool = true; var random_boolean = Math.random() > = . 95; if(random_boolean) { bool = false }; return bool; }

> cho (var i = 1; i <= 1000000; i++) { db.test. chèn( { _id. i, tên. "tên" + i, flag: ngẫu nhiênBool() } ) }

WriteResult({ "nInserted" . 1 })

> db. kiểm tra. tìm(). đếm()

1000000

> db. kiểm tra. tìm( { cờ. false } ). đếm()

49949

Tạo chỉ mục trên trường cờ và xem kích thước chỉ mục bằng db. kiểm tra. thống kê()

Vỏ bọc

1

2

3

4

5

6

7

> db. kiểm tra. createIndex( { flag. 1 } )

{ "createdCollectionAutomatically" . sai,

"numIndexes Before" . 1,

"numIndexesafter" . 2,

"ok" . 1 }

> db. kiểm tra. thống kê(). kích thước chỉ mục

{ "_id_" . 13103104, "flag_1" . 4575232 }

Chỉ mục chúng tôi đã tạo là 4575232 byte

Kiểm tra một số truy vấn đơn giản để trích xuất tài liệu dựa trên giá trị cờ và xem cách sử dụng chỉ mục và thời gian thực hiện. (Với mục đích này, chúng tôi sử dụng một đối tượng có thể giải thích được)

Vỏ bọc

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

// tạo đối tượng có thể giải thích object

> var exp = db.test. giải thích( "executionStats" )

 

// giải thích bộ sưu tập hoàn thành scan

> exp. tìm( {  } )

{

"Planner truy vấn" . {

"plannerVersion" . 1,

"không gian tên" . "kiểm tra. test",

"indexFilterSet" . sai,

"parsedQuery" . {

 

},

"Kế hoạch chiến thắng" . {

"giai đoạn" . "COLLSCAN",

"hướng" . "chuyển tiếp"

},

"kế hoạch bị từ chối" . [ ]

},

"executionStats" . {

"executionSuccess" . true,

"nReturned" . 1000000,

"executionTimeMillis" . 250,

"totalKeysExamined" . 0,

"totalDocsExamined" . 1000000,

"Giai đoạn thực thi" . {

"giai đoạn" . "COLLSCAN",

"nReturned" . 1000000,

"executionTimeMillisEstimate" . 200,

"hoạt động" . 1000002,

"nâng cao" . 1000000,

"needTime" . 1,

"needYield" . 0,

"saveState" . 7812,

"restoreState" . 7812,

"isEOF" . 1,

"invalidates" . 0,

"hướng" . "chuyển tiếp",

"docsExamined" . 1000000

}

},

"serverInfo" . {

"máy chủ" . "ip-172-30-2-181",

"cổng" . 27017,

"phiên bản" . "4. 0. 4",

"gitVersion" . "f288a3bdf201007f3693c58e140056adf8b04839"

},

"ok" . 1

}

 

// tìm cờ tài liệu cờ=true

> exp. tìm( { cờ. true } )

{

"Planner truy vấn" . {

"plannerVersion" . 1,

"không gian tên" . "kiểm tra. test",

"indexFilterSet" . sai,

"parsedQuery" . {

"cờ" . {

"$eq" . đúng

}

},

"Kế hoạch chiến thắng" . {

"giai đoạn" . "TÌM HIỂU",

"Giai đoạn đầu vào" . {

"giai đoạn" . "IXSCAN",

"keyPattern" . {

"cờ" . 1

},

"indexName" . "flag_1",

"isMultiKey" . sai,

"multiKeyPath" . {

"cờ" . [ ]

},

"là duy nhất" . sai,

"isSparse" . false,

"isPartial" . sai,

"indexVersion" . 2,

"hướng" . "chuyển tiếp",

"giới hạn chỉ mục" . {

"cờ" . [

"[đúng rồi]"

]

}

}

},

"kế hoạch bị từ chối" . [ ]

},

"executionStats" . {

"executionSuccess" . true,

"nĐã trả lại" . 950051,

"executionTimeMillis" . 1028,

"totalKeysExamined" . 950051,

"totalDocsExamined" . 950051,

"Giai đoạn thực thi" . {

"giai đoạn" . "TÌM HIỂU",

"nĐã trả lại" . 950051,

"executionTimeMillisEstimate" . 990,

"hoạt động" . 950052,

"nâng cao" . 950051,

"needTime" . 0,

"needYield" . 0,

"saveState" . 7422,

"restoreState" . 7422,

"isEOF" . 1,

"invalidates" . 0,

"docsExamined" . 950051,

"alreadyHasObj" . 0,

"Giai đoạn đầu vào" . {

"giai đoạn" . "IXSCAN",

"nĐã trả lại" . 950051,

"executionTimeMillisEstimate" . 350,

"hoạt động" . 950052,

"nâng cao" . 950051,

"needTime" . 0,

"needYield" . 0,

"saveState" . 7422,

"restoreState" . 7422,

"isEOF" . 1,

"invalidates" . 0,

"keyPattern" . {

"cờ" . 1

},

"indexName" . "flag_1",

"isMultiKey" . sai,

"multiKeyPath" . {

"cờ" . [ ]

},

"là duy nhất" . sai,

"isSparse" . false,

"isPartial" . sai,

"indexVersion" . 2,

"hướng" . "chuyển tiếp",

"giới hạn chỉ mục" . {

"cờ" . [

"[đúng rồi]"

]

},

"keysExamined" . 950051,

"tìm kiếm" . 1,

"dupsTested" . 0,

"dupsDropped" . 0,

"seenInvalidated" . 0

}

}

},

"serverInfo" . {

"máy chủ" . "ip-172-30-2-181",

"cổng" . 27017,

"phiên bản" . "4. 0. 4",

"gitVersion" . "f288a3bdf201007f3693c58e140056adf8b04839"

},

"ok" . 1

}

 

// tìm các tài liệu với flag=false

> exp. find( { flag. false } )

{

"Planner truy vấn" . {

"plannerVersion" . 1,

"không gian tên" . "kiểm tra. test",

"indexFilterSet" . sai,

"parsedQuery" . {

"cờ" . {

"$eq" . sai

}

},

"Kế hoạch chiến thắng" . {

"giai đoạn" . "TÌM HIỂU",

"Giai đoạn đầu vào" . {

"giai đoạn" . "IXSCAN",

"keyPattern" . {

"cờ" . 1

},

"indexName" . "flag_1",

"isMultiKey" . sai,

"multiKeyPath" . {

"cờ" . [ ]

},

"là duy nhất" . sai,

"isSparse" . false,

"isPartial" . sai,

"indexVersion" . 2,

"hướng" . "chuyển tiếp",

"giới hạn chỉ mục" . {

"cờ" . [

"[sai, sai]"

]

}

}

},

"kế hoạch bị từ chối" . [ ]

},

"executionStats" . {

"executionSuccess" . true,

"nReturned" . 49949,

"executionTimeMillis" . 83,

"totalKeysExamined" . 49949,

"totalDocsExamined" . 49949,

"Giai đoạn thực thi" . {

"giai đoạn" . "TÌM HIỂU",

"nReturned" . 49949,

"executionTimeMillisEstimate" . 70,

"hoạt động" . 49950,

"advanced" . 49949,

"needTime" . 0,

"needYield" . 0,

"saveState" . 390,

"restoreState" . 390,

"isEOF" . 1,

"invalidates" . 0,

"docsExamined" . 49949,

"alreadyHasObj" . 0,

"Giai đoạn đầu vào" . {

"giai đoạn" . "IXSCAN",

"nReturned" . 49949,

"executionTimeMillisEstimate" . 10,

"hoạt động" . 49950,

"advanced" . 49949,

"needTime" . 0,

"needYield" . 0,

"saveState" . 390,

"restoreState" . 390,

"isEOF" . 1,

"invalidates" . 0,

"keyPattern" . {

"cờ" . 1

},

"indexName" . "flag_1",

"isMultiKey" . sai,

"multiKeyPath" . {

"cờ" . [ ]

},

"là duy nhất" . sai,

"isSparse" . false,

"isPartial" . sai,

"indexVersion" . 2,

"hướng" . "chuyển tiếp",

"giới hạn chỉ mục" . {

"cờ" . [

"[sai, sai]"

]

},

"keysExamined" . 49949,

"tìm kiếm" . 1,

"dupsTested" . 0,

"dupsDropped" . 0,

"seenInvalidated" . 0

}

}

},

"serverInfo" . {

"máy chủ" . "ip-172-30-2-181",

"cổng" . 27017,

"phiên bản" . "4. 0. 4",

"gitVersion" . "f288a3bdf201007f3693c58e140056adf8b04839"

},

"ok" . 1

}

Như mong đợi, MongoDB thực hiện COLLSCAN khi tìm kiếm db. test. tìm thấy( {} ). Điều quan trọng ở đây là phải mất 250 mili giây để quét toàn bộ bộ sưu tập

In both the other cases – find ({flag. đúng}) và tìm ({cờ. false}) – MongoDB sử dụng chỉ mục. But let’s have a look at the execution times

  • cho db. kiểm tra. tìm ({cờ. true}) là 1028 mili giây. Thời gian thực hiện nhiều hơn so với COLLSCAN. Chỉ mục trong trường hợp này là không hữu ích. COLLSCAN nên được ưu tiên hơn
  • cho db. kiểm tra. tìm ({cờ. false}) là 83 mili giây. cái này tốt. The index in this case is very useful

Bây giờ, tạo chỉ mục một phần trên trường cờ. Để làm điều đó, chúng ta phải sử dụng tùy chọn PartialFilterExpression trên lệnh createIndex

Vỏ bọc

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

// bỏ chỉ mục hiện có index

> db. test. dropIndex( { cờ. 1} )

{ "nIndexesWas" . 2, "ok" . 1 }

 

// tạo chỉ mục một phần only on the false values

> db. kiểm tra. createIndex( { flag . 1 }, { partialFilterExpression .   { cờ. false }  } )<

{

"createdCollectionAutomatically" . sai,

"numIndexes Before" . 1,

"numIndexesafter" . 2,

"ok" . 1

}

 

// lấy kích thước chỉ mục size  

> db. kiểm tra. thống kê(). kích thước chỉ mục

{ "_id_" . 13103104, "flag_1" . 278528 }

 

// tạo đối tượng explainalbe object

> var exp = db.test. giải thích( "executionStats" )

 

// kiểm tra các truy vấn cho flag=false

> exp. tìm({ cờ. false  })

{

"Planner truy vấn" . {

"plannerVersion" . 1,

"không gian tên" . "kiểm tra. test",

"indexFilterSet" . sai,

"parsedQuery" . {

"cờ" . {

"$eq" . sai

}

},

"Kế hoạch chiến thắng" . {

"giai đoạn" . "TÌM HIỂU",

"Giai đoạn đầu vào" . {

"giai đoạn" . "IXSCAN",

"keyPattern" . {

"cờ" . 1

},

"indexName" . "flag_1",

"isMultiKey" . sai,

"multiKeyPath" . {

"cờ" . [ ]

},

"là duy nhất" . sai,

"isSparse" . false,

"isPartial" . true,

"indexVersion" . 2,

"hướng" . "chuyển tiếp",

"giới hạn chỉ mục" . {

"cờ" . [

"[sai, sai]"

]

}

}

},

"kế hoạch bị từ chối" . [ ]

},

"executionStats" . {

"executionSuccess" . true,

"nReturned" . 49949,

"executionTimeMillis" . 80,

"totalKeysExamined" . 49949,

"totalDocsExamined" . 49949,

"Giai đoạn thực thi" . {

"giai đoạn" . "TÌM HIỂU",

"nReturned" . 49949,

"executionTimeMillisEstimate" . 80,

"hoạt động" . 49950,

"advanced" . 49949,

"needTime" . 0,

"needYield" . 0,

"saveState" . 390,

"restoreState" . 390,

"isEOF" . 1,

"invalidates" . 0,

"docsExamined" . 49949,

"alreadyHasObj" . 0,

"Giai đoạn đầu vào" . {

"giai đoạn" . "IXSCAN",

"nReturned" . 49949,

"executionTimeMillisEstimate" . 40,

"hoạt động" . 49950,

"advanced" . 49949,

"needTime" . 0,

"needYield" . 0,

"saveState" . 390,

"restoreState" . 390,

"isEOF" . 1,

"invalidates" . 0,

"keyPattern" . {

"cờ" . 1

},

"indexName" . "flag_1",

"isMultiKey" . sai,

"multiKeyPath" . {

"cờ" . [ ]

},

"là duy nhất" . sai,

"isSparse" . false,

"isPartial" . true,

"indexVersion" . 2,

"hướng" . "chuyển tiếp",

"giới hạn chỉ mục" . {

"cờ" . [

"[sai, sai]"

]

},

"keysExamined" . 49949,

"tìm kiếm" . 1,

"dupsTested" . 0,

"dupsDropped" . 0,

"seenInvalidated" . 0

}

}

},

"serverInfo" . {

"máy chủ" . "ip-172-30-2-181",

"cổng" . 27017,

"phiên bản" . "4. 0. 4",

"gitVersion" . "f288a3bdf201007f3693c58e140056adf8b04839"

},

"ok" . 1

}

 

// kiểm tra các truy vấn cho flag=true

> exp. tìm({ cờ. true  })

{

"Planner truy vấn" . {

"plannerVersion" . 1,

"không gian tên" . "kiểm tra. test",

"indexFilterSet" . sai,

"parsedQuery" . {

"cờ" . {

"$eq" . đúng

}

},

"Kế hoạch chiến thắng" . {

"giai đoạn" . "COLLSCAN",

"bộ lọc" . {

"cờ" . {

"$eq" . đúng

}

},

"hướng" . "chuyển tiếp"

},

"kế hoạch bị từ chối" . [ ]

},

"executionStats" . {

"executionSuccess" . true,

"nĐã trả lại" . 950051,

"executionTimeMillis" . 377,

"totalKeysExamined" . 0,

"totalDocsExamined" . 1000000,

"Giai đoạn thực thi" . {

"giai đoạn" . "COLLSCAN",

"bộ lọc" . {

"cờ" . {

"$eq" . đúng

}

},

"nĐã trả lại" . 950051,

"executionTimeMillisEstimate" . 210,

"hoạt động" . 1000002,

"nâng cao" . 950051,

"needTime" . 49950,

"needYield" . 0,

"saveState" . 7812,

"restoreState" . 7812,

"isEOF" . 1,

"invalidates" . 0,

"hướng" . "chuyển tiếp",

"docsExamined" . 1000000

}

},

"serverInfo" . {

"máy chủ" . "ip-172-30-2-181",

"cổng" . 27017,

"phiên bản" . "4. 0. 4",

"gitVersion" . "f288a3bdf201007f3693c58e140056adf8b04839"

},

"ok" . 1

}

Chúng ta có thể nhận thấy những điều sau đây

  • db. kiểm tra. tìm ({cờ. false}) sử dụng chỉ mục và thời gian thực hiện ít nhiều giống như trước đây
  • db. kiểm tra. tìm ({cờ. true}) không sử dụng chỉ mục. MongoDB thực hiện COLLSCAN và việc thực thi tốt hơn trước
  • lưu ý kích thước chỉ mục chỉ là 278528 byte. bây giờ Một khoản tiết kiệm lớn so với chỉ mục hoàn chỉnh trên cờ. Sẽ không có chi phí trong quá trình viết trong phần lớn các tài liệu

Tùy chọn một phần trên các loại chỉ mục khác

Bạn có thể sử dụng tùy chọn partialFilterExpression ngay cả trong các chỉ mục phức hợp hoặc các loại chỉ mục khác. Hãy xem một ví dụ về chỉ số phức hợp

Chèn một số tài liệu vào bộ sưu tập sinh viên

Vỏ bọc

1

2

3

4

5

6

7

8

9

10

db. học sinh. chèn( [

{ _id. 1, tên. "John", lớp. "Toán", điểm. 10 },

{ _id. 2, tên. "Peter", lớp. "Tiếng Anh", điểm. 6 },

{ _id. 3, tên. "Maria" , lớp. "Địa lý", điểm. 8 },

{ _id. 4, tên. "Alex" , lớp. "Địa lý", điểm. 5},

{ _id. 5, tên. "George" , lớp. "Toán", điểm. 7 },

{ _id. 6, tên. "Tony" , lớp. "Tiếng Anh", điểm. 9 },

{ _id. 7, tên. "Sam" , lớp. "Toán", điểm. 6 },

{ _id. 8, tên. "Tom" , lớp. "Tiếng Anh", điểm. 5 }

])

Tạo chỉ mục ghép một phần trên các trường tên và lớp cho điểm lớn hơn hoặc bằng 8

Vỏ bọc

1

2

3

4

5

6

7

> db. học sinh. createIndex( { tên. 1, lớp. 1  }, {< . partialFilterExpression: { điểm. { $gte. 8} } } )

{

"createdCollectionAutomatically" . sai,

"numIndexes Before" . 1,

"numIndexesafter" . 2,

"ok" . 1

}

Lưu ý rằng trường điểm không nhất thiết phải là một phần của chỉ mục

phạm vi truy vấn

Sử dụng bộ sưu tập sinh viên, bây giờ chúng tôi muốn hiển thị khi có thể sử dụng chỉ mục một phần

Điều quan trọng cần nhớ là chỉ mục một phần là “một phần”. Nó có nghĩa là nó không chứa tất cả các mục

Để MongoDB sử dụng nó, các điều kiện trong truy vấn phải bao gồm một biểu thức trên trường bộ lọc và các tài liệu được chọn phải là một tập hợp con của chỉ mục

Hãy xem một số ví dụ

Truy vấn sau đây có thể sử dụng chỉ mục vì chúng tôi đang chọn một tập hợp con của chỉ mục một phần

Vỏ bọc

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

> db. học sinh. tìm({tên. "Tony", điểm. {$gt. 8}})

{ "_id" . 6, "tên" . "Tony", "lớp" . "Tiếng Anh", "điểm" . 9 }

 

// hãy ' s nhìn at the explain

> db. học sinh. tìm({tên. "Tony", điểm. {$gt. 8}}). giải thích()

{

"Planner truy vấn" . {

"plannerVersion" . 1,

"không gian tên" . "kiểm tra. sinh viên",

"indexFilterSet" . sai,

"parsedQuery" . {

"$and" . [

{

"tên" . {

"$eq" . "Tony"

}

},

{

"điểm" . {

"$gt" . 8

}

}

]

},

"Kế hoạch chiến thắng" . {

"giai đoạn" . "TÌM HIỂU",

"bộ lọc" . {

"điểm" . {

"$gt" . 8

}

},

"Giai đoạn đầu vào" . {

"giai đoạn" . "IXSCAN",

"keyPattern" . {

"tên" . 1,

"lớp" . 1

},

"indexName" . "tên_1_lớp_1",

"isMultiKey" . sai,

"multiKeyPath" . {

"tên" . [ ],

"lớp" . [ ]

},

"là duy nhất" . sai,

"isSparse" . false,

"isPartial" . true,

"indexVersion" . 2,

"hướng" . "chuyển tiếp",

"giới hạn chỉ mục" . {

"tên" . [

"[\"Tony\", \"Tony\"]"

],

"lớp" . [

"[MinKey, MaxKey]"

]

}

}

},

"kế hoạch bị từ chối" . [ ]

},

"serverInfo" . {

"máy chủ" . "ip-172-30-2-181",

"cổng" . 27017,

"phiên bản" . "4. 0. 4",

"gitVersion" . "f288a3bdf201007f3693c58e140056adf8b04839"

},

"ok" . 1

}

Truy vấn sau đây không thể sử dụng chỉ mục vì điều kiện trên lớp > 5 không chọn tập hợp con của chỉ mục một phần. Vì vậy COLLSCAN là cần thiết

Vỏ bọc

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

> db. học sinh. tìm({tên. "Tony", điểm. {$gt. 5}}). giải thích()

{

"Planner truy vấn" . {

"plannerVersion" . 1,

"không gian tên" . "kiểm tra. sinh viên",

"indexFilterSet" . sai,

"parsedQuery" . {

"$and" . [

{

"tên" . {

"$eq" . "Tony"

}

},

{

"điểm" . {

"$gt" . 5

}

}

]

},

"Kế hoạch chiến thắng" . {

"giai đoạn" . "COLLSCAN",

"bộ lọc" . {

"$and" . [

{

"tên" . {

"$eq" . "Tony"

}

},

{

"điểm" . {

"$gt" . 5

}

}

]

},

"hướng" . "chuyển tiếp"

},

"kế hoạch bị từ chối" . [ ]

},

"serverInfo" . {

"máy chủ" . "ip-172-30-2-181",

"cổng" . 27017,

"phiên bản" . "4. 0. 4",

"gitVersion" . "f288a3bdf201007f3693c58e140056adf8b04839"

},

"ok" . 1

}

Ngay cả truy vấn sau đây cũng không thể sử dụng chỉ mục. Như chúng tôi đã nói, trường điểm không phải là một phần của chỉ mục. Điều kiện đơn giản về điểm là không đủ

Vỏ bọc

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

> db. học sinh. tìm({điểm. {$gt. 8}}). giải thích()

{

"Planner truy vấn" . {

"plannerVersion" . 1,

"không gian tên" . "kiểm tra. sinh viên",

"indexFilterSet" . sai,

"parsedQuery" . {

"điểm" . {

"$gt" . 8

}

},

"Kế hoạch chiến thắng" . {

"giai đoạn" . "COLLSCAN",

"bộ lọc" . {

"điểm" . {

"$gt" . 8

}

},

"hướng" . "chuyển tiếp"

},

"kế hoạch bị từ chối" . [ ]

},

"serverInfo" . {

"máy chủ" . "ip-172-30-2-181",

"cổng" . 27017,

"phiên bản" . "4. 0. 4",

"gitVersion" . "f288a3bdf201007f3693c58e140056adf8b04839"

},

"ok" . 1

}

Chỉ mục thưa thớt

Chỉ mục thưa thớt là chỉ mục chứa các mục chỉ dành cho các tài liệu có trường được lập chỉ mục

Vì MongoDB là một cơ sở dữ liệu không lược đồ nên không phải tất cả các tài liệu trong một bộ sưu tập nhất thiết phải chứa các trường giống nhau. Vì vậy, chúng tôi có hai tùy chọn khi tạo chỉ mục

  • tạo một chỉ mục "không thưa thớt" thông thường
    • chỉ mục chứa nhiều mục nhập như tài liệu
    • chỉ mục chứa các mục dưới dạng null cho tất cả các tài liệu không có trường được lập chỉ mục
  • tạo một chỉ mục thưa thớt
    • chỉ mục chứa nhiều mục nhập như tài liệu có trường được lập chỉ mục

Chúng tôi gọi nó là "thưa thớt" vì nó không chứa tất cả các tài liệu của bộ sưu tập

Ưu điểm chính của tùy chọn thưa thớt là giảm kích thước chỉ mục

Đây là cách tạo một chỉ mục thưa thớt

Vỏ bọc

1

db. người. createIndex( { thành phố. 1 }, { thưa thớt . : true } )

Các chỉ mục thưa thớt là một tập hợp con của các chỉ mục một phần. Trên thực tế, bạn có thể mô phỏng một chỉ mục thưa thớt bằng cách sử dụng định nghĩa sau đây về một phần

Vỏ bọc

1

2

3

4

db. người. createIndex(

{thành phố.   1},

{ partialFilterExpression. {thành phố. {$tồn tại. true} } }

)

Vì lý do này, các chỉ mục một phần được ưu tiên hơn các chỉ mục thưa thớt

kết luận

Lập chỉ mục một phần là một tính năng tuyệt vời trong MongoDB. Bạn nên cân nhắc sử dụng để đạt được những ưu điểm sau

Chỉ mục một phần trong MongoDB là gì?

Chỉ mục một phần chỉ lập chỉ mục các tài liệu trong bộ sưu tập đáp ứng biểu thức bộ lọc được chỉ định . Bằng cách lập chỉ mục một tập hợp con của các tài liệu trong một bộ sưu tập, các chỉ mục một phần có yêu cầu lưu trữ thấp hơn và giảm chi phí hiệu suất để tạo và duy trì chỉ mục.

số chỉ mục một phần là gì?

Chỉ mục bộ phận là chỉ mục được xây dựng trên một tập hợp con của bảng ; . Chỉ mục chứa các mục chỉ dành cho những hàng của bảng thỏa mãn vị từ.

MongoDB có thể sử dụng một phần của chỉ mục ghép không?

MongoDB có thể sử dụng giao điểm của các chỉ mục để thực hiện các truy vấn. Đối với các truy vấn chỉ định các điều kiện truy vấn phức hợp, nếu một chỉ mục có thể đáp ứng một phần của điều kiện truy vấn và một chỉ mục khác có thể đáp ứng một phần khác của điều kiện truy vấn, thì MongoDB có thể sử dụng giao điểm của hai chỉ mục để đáp ứng truy vấn

Làm cách nào để tạo một phần chỉ mục trong MongoDB Compass?

Để tạo chỉ mục trên bộ sưu tập qua Compass, bộ sưu tập phải chứa tài liệu. .
Nhấp vào nút Tạo chỉ mục. Từ tab Chỉ mục, nhấp vào nút Tạo Chỉ mục để hiển thị hộp thoại Tạo Chỉ mục
Không bắt buộc. Nhập tên chỉ mục. .
Thêm trường vào chỉ mục. Chỉ định một khóa chỉ mục