MongoDB đã giới thiệu db.collection.hideIndex()
trong MongoDB 4.4.
Phương pháp này ẩn một chỉ mục hiện có khỏi trình lập kế hoạch truy vấn. Điều này cho phép bạn đánh giá tác động tiềm ẩn của việc giảm chỉ mục mà không thực sự giảm chỉ mục.
Nếu ẩn nó có tác động tiêu cực, bạn có thể sử dụng db.collection.unhideIndex()
để hiện chỉ mục. Điều này giúp bạn không phải bỏ chỉ mục, sau đó tạo lại nó.
Ví dụ
Giả sử chúng ta có một bộ sưu tập có tên là pets
. Hãy trả về các chỉ mục hiện tại trên bộ sưu tập đó.
db.pets.getIndexes()
Kết quả:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "name" : 1, "type" : -1 }, "name" : "idx_name_1_type_-1" }, { "v" : 2, "key" : { "weight" : -1 }, "name" : "idx_weight_-1" } ]
Chúng ta có thể thấy rằng nó có ba chỉ mục. Hãy chọn cái thứ ba có tên là idx_weight_-1
cho ví dụ của chúng tôi.
Trước tiên, hãy xem kế hoạch truy vấn trông như thế nào khi chúng tôi chạy các truy vấn sử dụng chỉ mục đó.
db.pets.find( { weight: { $gt: 10 } } ).explain()
Tại đây, chúng tôi đang tìm kiếm những vật nuôi có trọng lượng vượt quá một trọng lượng nhất định. Chúng tôi đang sử dụng explain()
để hiển thị kế hoạch truy vấn thay vì kết quả thực tế.
Đây là kế hoạch truy vấn trông như thế nào cho truy vấn này:
{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "PetHouse.pets", "indexFilterSet" : false, "parsedQuery" : { "weight" : { "$gt" : 10 } }, "queryHash" : "CEB852E7", "planCacheKey" : "851FBDB5", "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "weight" : -1 }, "indexName" : "idx_weight_-1", "isMultiKey" : false, "multiKeyPaths" : { "weight" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "weight" : [ "[inf.0, 10.0)" ] } } }, "rejectedPlans" : [ ] }, "ok" : 1 }
Chúng ta có thể thấy rằng nó sử dụng IXSCAN
có nghĩa là nó đã sử dụng chỉ mục.
Bây giờ, hãy ẩn chỉ mục.
Ẩn chỉ mục
Đây là nơi hideIndex()
xuất hiện. Chúng tôi có thể sử dụng nó để ẩn chỉ mục để nó không hiển thị trên kế hoạch truy vấn như đã làm trong ví dụ trước.
db.pets.hideIndex("idx_weight_-1")
Đầu ra:
{ "hidden_old" : false, "hidden_new" : true, "ok" : 1 }
Đầu ra của hideIndex()
phương thức hiển thị giá trị cũ cho hidden
trường (trong trường hợp này là false
) và giá trị mới (trong trường hợp này là true
).
Tuy nhiên, nếu chúng tôi ẩn một chỉ mục đã bị ẩn (hoặc hiện một chỉ mục đã bị ẩn), những chỉ mục này sẽ không được hiển thị và chúng tôi chỉ nhận được những điều sau:
{ "ok" : 1 }
Trong mọi trường hợp, chỉ mục hiện bị ẩn.
Kiểm tra lại Kế hoạch truy vấn
Hãy chạy lại truy vấn trước đó để xem kế hoạch truy vấn bây giờ trông như thế nào.
db.pets.find( { weight: { $gt: 10 } } ).explain()
Kết quả:
{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "PetHouse.pets", "indexFilterSet" : false, "parsedQuery" : { "weight" : { "$gt" : 10 } }, "queryHash" : "CEB852E7", "planCacheKey" : "851FBDB5", "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "weight" : { "$gt" : 10 } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "ok" : 1 }
Lần này chúng tôi nhận được COLLSCAN
, có nghĩa là nó không sử dụng chỉ mục - nó đã quét bộ sưu tập.
Kiểm tra xem một chỉ mục có bị ẩn hay không
Bạn có thể sử dụng getIndexes()
để kiểm tra xem một chỉ mục có bị ẩn hay không.
Vì vậy, chúng tôi có thể chạy cùng một truy vấn mà chúng tôi đã chạy trước đó để trả về tất cả các chỉ mục:
db.pets.getIndexes()
Kết quả:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "name" : 1, "type" : -1 }, "name" : "idx_name_1_type_-1" }, { "v" : 2, "key" : { "weight" : -1 }, "name" : "idx_weight_-1", "hidden" : true } ]
Không thể ẩn chỉ mục? Kiểm tra Cài đặt này.
mongod
featureCompatibilityVersion
ít nhất phải là 4.4
trước khi bạn có thể ẩn các chỉ mục. Tuy nhiên, sau khi bị ẩn, chỉ mục sẽ vẫn bị ẩn ngay cả với featureCompatibilityVersion
đặt thành 4.2 trên tệp nhị phân MongoDB 4.4.
Bạn có thể kiểm tra featureCompatibilityVersion
cài đặt bằng mã sau:
db.adminCommand(
{
getParameter: 1,
featureCompatibilityVersion: 1
}
)
Bạn có thể đặt nó bằng setFeatureCompatibilityVersion
lệnh:
db.adminCommand( { setFeatureCompatibilityVersion: "4.4" } )
setFeatureCompatibilityVersion
lệnh cần được chạy trong admin
cơ sở dữ liệu.
Cũng lưu ý, bạn không thể ẩn _id
chỉ mục.