Hiệu suất đếm MongoDB
Bạn có thể sử dụng ensureIndex() để tăng hiệu suất của phương thức count() trong MongoDB. Để hiểu khái niệm này, chúng ta hãy tạo một bộ sưu tập với tài liệu. Truy vấn để tạo một bộ sưu tập với một tài liệu như sau - Show
> db.countPerformanceDemo.insertOne({"StudentName":"John","StudentCountryName":"US"}); { "acknowledged" : true, "insertedId" : ObjectId("5c8ebcf82f684a30fbdfd55f") } > db.countPerformanceDemo.insertOne({"StudentName":"Mike","StudentCountryName":"UK"}); { "acknowledged" : true, "insertedId" : ObjectId("5c8ebd042f684a30fbdfd560") } > db.countPerformanceDemo.insertOne({"StudentName":"David","StudentCountryName":"AUS"}); { "acknowledged" : true, "insertedId" : ObjectId("5c8ebd112f684a30fbdfd561") } > db.countPerformanceDemo.insertOne({"StudentName":"Carol","StudentCountryName":"US"}); { "acknowledged" : true, "insertedId" : ObjectId("5c8ebd1a2f684a30fbdfd562") } > db.countPerformanceDemo.insertOne({"StudentName":"Bob","StudentCountryName":"UK"}); { "acknowledged" : true, "insertedId" : ObjectId("5c8ebd212f684a30fbdfd563") } > db.countPerformanceDemo.insertOne({"StudentName":"David","StudentCountryName":"UK"}); { "acknowledged" : true, "insertedId" : ObjectId("5c8ebd9a2f684a30fbdfd564") } > db.countPerformanceDemo.insertOne({"StudentName":"David","StudentCountryName":"US"}); { "acknowledged" : true, "insertedId" : ObjectId("5c8ebd9e2f684a30fbdfd565") } Hiển thị tất cả các tài liệu từ một bộ sưu tập với sự trợ giúp của phương thức find(). Truy vấn như sau - > db.countPerformanceDemo.find().pretty(); Sau đây là đầu ra - { "_id" : ObjectId("5c8ebcf82f684a30fbdfd55f"), "StudentName" : "John", "StudentCountryName" : "US" } { "_id" : ObjectId("5c8ebd042f684a30fbdfd560"), "StudentName" : "Mike", "StudentCountryName" : "UK" } { "_id" : ObjectId("5c8ebd112f684a30fbdfd561"), "StudentName" : "David", "StudentCountryName" : "AUS" } { "_id" : ObjectId("5c8ebd1a2f684a30fbdfd562"), "StudentName" : "Carol", "StudentCountryName" : "US" } { "_id" : ObjectId("5c8ebd212f684a30fbdfd563"), "StudentName" : "Bob", "StudentCountryName" : "UK" } { "_id" : ObjectId("5c8ebd9a2f684a30fbdfd564"), "StudentName" : "David", "StudentCountryName" : "UK" } { "_id" : ObjectId("5c8ebd9e2f684a30fbdfd565"), "StudentName" : "David", "StudentCountryName" : "US" } Đây là truy vấn để có được dạng đếm () hiệu suất cao - > db.countPerformanceDemo.ensureIndex({"StudentName":1}); { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } Bây giờ, hãy triển khai phương thức đếm (). Nó đếm các bản ghi với StudentName “David” > db.countPerformanceDemo.find({"StudentName":"David"}).count(); Sau đây là đầu ra - 3 Nếu bạn, một nhà phát triển phụ trợ, phải mô tả công việc của mình, bạn sẽ nói gì? Chúng tôi đưa dữ liệu vào cơ sở dữ liệu và lấy lại dữ liệu nhanh nhất có thể. Lời khuyên tốt nhất của tôi? . Đơn giản hóa các mô hình dữ liệu của bạn. Đơn giản hóa các mẫu truy cập của bạn Hiệu suất trong MongoDBsố liệuNếu bạn đang sử dụng MongoDB, hai chỉ số này sẽ là người bạn tốt nhất của bạn
Tài liệu được quét/trả lại. nó có nghĩa là bạn đang đọc bao nhiêu tài liệu từ đĩa so với số lượng tài liệu bạn thực sự trả lại trong 5 hoặc 6 của mình. Lý tưởng nhất. cái này phải là 1 (mọi tài liệu đã đọc đều được trả về). Cách duy nhất để có được nó? . Các chỉ mục nằm trong bộ nhớ (hoặc nếu phù hợp), vì vậy MongoDB không phải đọc và lọc chúng từ đĩaIOPS. hoạt động I/O mỗi giây. Đó là, hoạt động trên đĩa. Nó tương quan với các tài liệu được quét vì chúng được đọc từ đĩa. Nhưng có nhiều nguồn IOPS hơn, ví dụ như viết. Mục tiêu của bạn là giữ IOPS dưới ngưỡng đó và càng thấp càng tốt. Thật khó để biết truy vấn của bạn tiêu tốn bao nhiêu IOPS, nhưng thật dễ dàng để biết tỷ lệ tài liệu được quét/tỷ lệ trả về Công cụLàm thế nào bạn có thể phân tích lý do tại sao cơ sở dữ liệu của bạn hoạt động như vậy? MongoDB Profiler Giải thích về công cụ lập kế hoạch 7 sau con trỏ của mình.
Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Bạn có thể sử dụng add 8 để lấy thêm dữ liệu về truy vấn
Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Có nhiều giai đoạn, nhưng những giai đoạn này là quan trọng nhất
Đây là một ví dụ về một trong những truy vấn của chúng tôi > db.countPerformanceDemo.find().pretty();2 Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Điều này không tốt vì nó đang quét toàn bộ bộ sưu tập một cái khác > db.countPerformanceDemo.find().pretty();3 Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Tại đây, bạn có thể thấy cả hai IXSCAN, được hợp nhất bởi và HOẶC. Sau đó, truy vấn đang tìm nạp tài liệu. Tôi đang đọc truy vấn từ trong ra ngoài. 9 được sử dụng để giải quyết một phần của truy vấn và > db.countPerformanceDemo.find().pretty();20 cho phần còn lại Đôi khi bạn sẽ nhận được FETCH ngay sau IXSCAN. điều đó có nghĩa là chỉ mục chỉ bao gồm một phần của bộ lọc. Sau đó, người lập kế hoạch cần đọc tài liệu từ đĩa để kết thúc bộ lọc Đơn giản hóa truy vấn của bạn$or$or là ác quỷ. Bạn, với tư cách là một lập trình viên, đã quen với việc suy nghĩ theo $ors. Bạn thêm một vài đô la, điều kiện của bạn trở nên rõ ràng hơn nhiều. Nhưng đoán xem? . Với mọi điều kiện bạn thêm vào $or, bạn đang thêm một tổ hợp tham số nữa Người lập kế hoạch giải quyết tất cả những kết hợp đó như thế nào? Bạn có nhớ 7 ở trên không? > db.countPerformanceDemo.find().pretty();7 Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Các chỉ số được sử dụng? > db.countPerformanceDemo.find().pretty();8 Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Và đây là một mẹo khác. các chỉ mục lớn hơn có thể bao gồm các truy vấn nhỏ hơn miễn là các trường nằm ở đầu chỉ mục. Điều gì sẽ xảy ra nếu tôi thêm $or? > db.countPerformanceDemo.find().pretty();9 Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Sau đó, sẽ cần 4 kết hợp { "_id" : ObjectId("5c8ebcf82f684a30fbdfd55f"), "StudentName" : "John", "StudentCountryName" : "US" } { "_id" : ObjectId("5c8ebd042f684a30fbdfd560"), "StudentName" : "Mike", "StudentCountryName" : "UK" } { "_id" : ObjectId("5c8ebd112f684a30fbdfd561"), "StudentName" : "David", "StudentCountryName" : "AUS" } { "_id" : ObjectId("5c8ebd1a2f684a30fbdfd562"), "StudentName" : "Carol", "StudentCountryName" : "US" } { "_id" : ObjectId("5c8ebd212f684a30fbdfd563"), "StudentName" : "Bob", "StudentCountryName" : "UK" } { "_id" : ObjectId("5c8ebd9a2f684a30fbdfd564"), "StudentName" : "David", "StudentCountryName" : "UK" } { "_id" : ObjectId("5c8ebd9e2f684a30fbdfd565"), "StudentName" : "David", "StudentCountryName" : "US" }0 Vào chế độ toàn màn hình Thoát chế độ toàn màn hình trường không chuẩn hóaNếu bạn thấy mình đang lọc theo nhiều trường trong $or hoặc sắp xếp theo nhiều trường, hãy cân nhắc thêm một trường không chuẩn hóa (dựa trên các trường khác) Vâng, lời xin lỗi của tôi với hình thức bình thường thứ ba Hãy tiếp tục đọc, chúng tôi sẽ sớm đưa ra một ví dụ bằng cách sử dụng cái gọi là > db.countPerformanceDemo.find().pretty();22 null luôn là giá trị tối thiểuĐây là một thủ thuật nhỏ, nhưng vẫn hữu ích. Giả sử bạn có một trường nullable và bạn phải lọc (hoặc sắp xếp giảm dần) theo trường đó Bạn có thể thấy mình đang sử dụng một truy vấn tương tự như thế này { "_id" : ObjectId("5c8ebcf82f684a30fbdfd55f"), "StudentName" : "John", "StudentCountryName" : "US" } { "_id" : ObjectId("5c8ebd042f684a30fbdfd560"), "StudentName" : "Mike", "StudentCountryName" : "UK" } { "_id" : ObjectId("5c8ebd112f684a30fbdfd561"), "StudentName" : "David", "StudentCountryName" : "AUS" } { "_id" : ObjectId("5c8ebd1a2f684a30fbdfd562"), "StudentName" : "Carol", "StudentCountryName" : "US" } { "_id" : ObjectId("5c8ebd212f684a30fbdfd563"), "StudentName" : "Bob", "StudentCountryName" : "UK" } { "_id" : ObjectId("5c8ebd9a2f684a30fbdfd564"), "StudentName" : "David", "StudentCountryName" : "UK" } { "_id" : ObjectId("5c8ebd9e2f684a30fbdfd565"), "StudentName" : "David", "StudentCountryName" : "US" }2 Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Nghĩa là, nếu trường rỗng, thì nó sẽ vượt qua bộ lọc. Còn không thì so sánh. Chúng tôi đã sử dụng bộ lọc này để kiểm tra xem một người chơi có thể tham gia trận đấu hay không dựa trên cấp độ của họ và giới hạn cấp độ của trận đấu Đó là một $ hoặc. Chúng tôi không thích $ors. Điều gì sẽ xảy ra nếu chúng ta so sánh giá trị của mình với null? { "_id" : ObjectId("5c8ebcf82f684a30fbdfd55f"), "StudentName" : "John", "StudentCountryName" : "US" } { "_id" : ObjectId("5c8ebd042f684a30fbdfd560"), "StudentName" : "Mike", "StudentCountryName" : "UK" } { "_id" : ObjectId("5c8ebd112f684a30fbdfd561"), "StudentName" : "David", "StudentCountryName" : "AUS" } { "_id" : ObjectId("5c8ebd1a2f684a30fbdfd562"), "StudentName" : "Carol", "StudentCountryName" : "US" } { "_id" : ObjectId("5c8ebd212f684a30fbdfd563"), "StudentName" : "Bob", "StudentCountryName" : "UK" } { "_id" : ObjectId("5c8ebd9a2f684a30fbdfd564"), "StudentName" : "David", "StudentCountryName" : "UK" } { "_id" : ObjectId("5c8ebd9e2f684a30fbdfd565"), "StudentName" : "David", "StudentCountryName" : "US" }3 Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Tức là null luôn là giá trị thấp hơn khi so sánh (ngoại trừ đối tượng MinKey sẽ nói sau) Truy vấn của chúng tôi có thể được đơn giản hóa bằng cách này 0Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Nó hoạt động với $lt và $lte (thấp hơn và thấp hơn hoặc bằng). > db.countPerformanceDemo.find().pretty();23 > db.countPerformanceDemo.find().pretty();24 vì đối tượng có null sẽ ở cuối sắp xếp. Số lượng rất tốn kém trong MongoDBĐếm có vẻ là một hoạt động dễ dàng, nhưng nó không phải là. Ngay cả khi bạn có một chỉ mục, MongoDB cần duyệt qua chỉ mục do cách MongoDB xây dựng cây B. chúng không lưu trữ số lá mà cây con có. Vì vậy, họ cần duyệt qua chỉ mục cho đến khi kết thúc Một lần nữa, nếu bạn đang đếm bằng cách sử dụng truy vấn với $or, thì việc đếm thậm chí còn phức tạp hơn. truy vấn cần tính đến các tài liệu lặp lại có thể Ví dụ: chúng tôi đã sử dụng số lượng để tính toán vị trí của người chơi trong bảng xếp hạng (truy vấn ban đầu thậm chí còn phức tạp hơn) 1Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Nó yêu cầu một số chỉ mục để đếm 2Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Làm thế nào chúng ta có thể tránh tính vào một số chỉ mục? Ví dụ. > db.countPerformanceDemo.find().pretty();25 Với trường mới đó, chúng tôi chỉ yêu cầu một chỉ mục duy nhất. Chỉ mục. 3Vào chế độ toàn màn hình Thoát chế độ toàn màn hình Đây được gọi là Mẫu Tóm tắt Cách xây dựng chỉ mụcOk, các chỉ mục là công cụ tốt nhất của chúng tôi để giữ cho MongoDB hoạt động hiệu quả nhất có thể. Vì vậy, bước tiếp theo, làm thế nào để chúng ta biết chúng ta nên xây dựng những chỉ mục nào? Cố vấn hiệu suấtNếu bạn đang ở trong Atlas, hãy sử dụng Cố vấn hiệu suất Tại một thời điểm nào đó, bạn sẽ biết hệ thống của mình tốt hơn Trình cố vấn hiệu suất, nhưng đó là một điểm khởi đầu tốt Sao chép bộ sưu tập sản xuất của bạn và giải thích () nó ở địa phươngKiểm tra kỹ các chỉ mục của bạn trước khi đưa chúng vào sản xuất. - cần rất nhiều IOPS để xây dựng chúng
Hãy nhớ những gì chúng ta đã nói trước đây
Nhân tiện, có các giai đoạn chặn và không chặn, nghĩa là một giai đoạn cần đợi giai đoạn trước đó trước khi có thể bắt đầu tính toán kết quả ESR. Phạm vi sắp xếp bằng nhauBạn đã bao giờ tự hỏi những lĩnh vực nào nên đi đầu tiên trong một chỉ mục?
ESR là quy tắc hữu ích nhất mà bạn sẽ tìm thấy để xây dựng các chỉ mục. Bạn nên đọc càng nhiều càng tốt về nó cho đến khi bạn hiểu nó Bài đăng này của Alex Belilacqua là một viên ngọc quý phân biệt bằngNếu bạn có hai trường sắp được lọc theo $eq, thì trường nào nên thực hiện trước? Câu trả lời là nó không quan trọng. Bạn không cần phải lo lắng về việc có một cây cân đối hơn Chỉ cần ghi nhớ quy tắc ESR. Nếu một trong số họ đi vào > db.countPerformanceDemo.find().pretty();26 hoặc > db.countPerformanceDemo.find().pretty();27, thì nó sẽ đi sau quá trình tái đầu tưXây dựng một chỉ mục là một trong những hoạt động tốn kém nhất. IOPS của bạn sẽ trở nên tồi tệ. Nếu bạn cần làm điều đó trong môi trường sản xuất của mình và bộ sưu tập của bạn đủ lớn, thì chúng tôi khuyên bạn nên sử dụng quy trình cuốn chiếu. Nó bắt đầu xây dựng chỉ mục ở cấp độ thứ cấp, sau đó thăng cấp nó lên cấp độ chính sau khi quá trình xây dựng kết thúc. Bạn sẽ có thể tạo bất kỳ chỉ mục nào ngay cả khi tải cơ sở dữ liệu của bạn cao Trong Atlas, chỉ cần một cú nhấp chuột Xóa / Ẩn chỉ mụcBạn càng có nhiều chỉ số, điều tồi tệ nhất đối với người lập kế hoạch. Trình lập kế hoạch chạy truy vấn thông qua các chỉ mục mà nó có và sau đó chọn cách hứa hẹn nhất Một lần nữa, đếm khi bạn có nhiều chỉ mục là khá tệ Đôi khi, bạn không thể xóa một chỉ mục trong sản xuất. Bạn có thể kiểm tra bằng trình hồ sơ của mình nếu nó có thể bị xóa nhưng bạn có thể không 100%. Một truy vấn không thường xuyên có thể khởi chạy COLLSCAN và sau đó bạn sẽ bỏ lỡ chỉ mục đó May mắn thay, kể từ MongoDB 4. 4 bạn có thể ẩn chỉ mục. Chúng tôi sử dụng chúng để phát hiện những chỉ mục nào chúng tôi có thể xóa một cách an toàn MongoDB có được đếm nhanh hơn find không?bộ sưu tập. count() không có tham số sẽ đếm tất cả tài liệu trong bộ sưu tập trong khi db. thu thập. find() không có tham số khớp với tất cả các tài liệu trong một bộ sưu tập và việc thêm vào count() sẽ đếm chúng, vì vậy không có sự khác biệt .
MongoDB có cung cấp hiệu suất cao không?MongoDB là cơ sở dữ liệu tài liệu NoSQL hàng đầu dành cho các nhà phát triển hiện đại làm việc trên các ứng dụng hiệu năng cao . Với các tài liệu giống như JSON, MongoDB nổi bật với khả năng chia tỷ lệ theo chiều ngang và cân bằng tải, mang đến cho các nhà phát triển sự cân bằng tuyệt vời giữa khả năng tùy chỉnh và khả năng mở rộng.
MongoDB đếm tổng số bản ghi như thế nào?count() được sử dụng để trả về số lượng tài liệu khớp với truy vấn find(). db. thu thập. Phương thức đếm () không thực hiện thao tác tìm () mà thay vào đó đếm và trả về số lượng kết quả khớp với truy vấn.
Tại sao MongoDB có hiệu suất cao?MongoDB sử dụng hệ thống khóa để đảm bảo tính nhất quán của tập dữ liệu. Nếu một số hoạt động nhất định đang chạy lâu hoặc hình thành hàng đợi, hiệu suất sẽ giảm khi các yêu cầu và hoạt động chờ khóa |