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ọc1
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 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ọc1
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ọc1
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ọc1
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 } } ] 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ọc1
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ọc1
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ọc1
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ọc1
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ọc1
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ọc1
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ọc1
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