Lập chỉ mục Mongoose trong mã sản xuất


124

Theo tài liệu Mongoose cho MongooseJSMongoDB/ Node.js:

Khi ứng dụng của bạn khởi động, Mongoose sẽ tự động gọi ensureIndextừng chỉ mục đã xác định trong lược đồ của bạn. Mặc dù tốt cho quá trình phát triển, nhưng hành vi này nên được vô hiệu hóa trong quá trình sản xuất vì việc tạo chỉ mục có thể gây ra tác động đáng kể đến hiệu suất. Vô hiệu hóa hành vi bằng cách đặt autoIndextùy chọn của giản đồ của bạn thành sai.

Điều này dường như hướng dẫn loại bỏ tự động lập chỉ mục khỏi mongoose trước khi triển khai để tối ưu hóa Mongoose khỏi hướng dẫn Mongo đi và lướt qua tất cả các chỉ mục khi khởi động ứng dụng, điều này có vẻ hợp lý.

Cách thích hợp để xử lý lập chỉ mục trong mã sản xuất là gì? Có lẽ một tập lệnh bên ngoài sẽ tạo chỉ mục? Hoặc có thể ensureIndexlà không cần thiết nếu một ứng dụng duy nhất là người đọc / người viết duy nhất cho một bộ sưu tập bởi vì nó sẽ tiếp tục một chỉ mục mỗi khi ghi DB xảy ra?

Chỉnh sửa: Để bổ sung, MongoDB cung cấp tài liệu tốt về cách thực hiện lập chỉ mục, nhưng không phải lý do tại sao hoặc khi nào các chỉ thị lập chỉ mục rõ ràng nên được thực hiện. Đối với tôi, có vẻ như các chỉ mục nên được ứng dụng người viết cập nhật tự động trên các bộ sưu tập có chỉ mục hiện có và đó ensureIndexthực sự là việc chỉ làm một lần (được thực hiện khi một chỉ mục mới đang được áp dụng), trong trường hợp đó Mongoose's autoIndexphải là một no-op khi khởi động lại máy chủ bình thường.

Câu trả lời:


135

Tôi chưa bao giờ hiểu tại sao tài liệu Mongoose lại khuyến nghị vô hiệu hóa autoIndextrong sản xuất. Khi chỉ mục đã được thêm vào, các ensureIndexcuộc gọi tiếp theo sẽ chỉ thấy rằng chỉ mục đã tồn tại và sau đó trả về. Vì vậy, nó chỉ ảnh hưởng đến hiệu suất khi bạn lần đầu tiên tạo chỉ mục và tại thời điểm đó các bộ sưu tập thường trống nên dù sao thì việc tạo chỉ mục cũng sẽ nhanh chóng.

Đề xuất của tôi là để autoIndexkích hoạt trừ khi bạn gặp một tình huống cụ thể mà nó gây rắc rối cho bạn; chẳng hạn như nếu bạn muốn thêm một chỉ mục mới vào một bộ sưu tập hiện có có hàng triệu tài liệu và bạn muốn kiểm soát nhiều hơn khi nó được tạo.


10
Tôi có một câu hỏi cần thêm ... Điều gì sẽ xảy ra nếu tôi đặt nó là false? Hơn các chỉ mục sẽ được tạo ra khi tôi chèn dữ liệu hay tôi cần tạo nó một cách rõ ràng. Tôi xin lỗi nếu đây là một câu hỏi mới bắt đầu nhưng sẽ thực sự hữu ích nếu bạn trả lời.
Saransh Mohapatra

5
@SaranshMohapatra Khi autoIndexsai, bạn cần gọi ensureIndexes trên mô hình của mình để tạo các chỉ mục của nó.
JohnnyHK

Tôi sẽ phải gọi nó mỗi lần hay chỉ một lần xác định mô hình?
Saransh Mohapatra

@SaranshMohapatra khi bạn xác định (biên dịch) mô hình của mình. Tôi làm điều đó khi lần đầu tiên khởi động ứng dụng. Bây giờ suy nghĩ khó là quyết định loại bỏ tất cả các chỉ mục và tạo lại chúng, trong trường hợp lược đồ của bạn thay đổi.
Moss,

3
@JohnnyHK bạn có còn đồng ý với câu trả lời của mình khi đã gần đến năm 2016 không?
Alexander Mills

41

Mặc dù tôi đồng ý với câu trả lời được chấp nhận, nhưng điều đáng chú ý là theo hướng dẫn sử dụng MongoDB , đây không phải là cách được khuyến nghị để thêm chỉ mục trên máy chủ sản xuất:

Nếu ứng dụng của bạn bao gồm các hoạt động ensureIndex () và một chỉ mục không tồn tại cho các mối quan tâm về hoạt động khác, việc xây dựng chỉ mục có thể có tác động nghiêm trọng đến hiệu suất của cơ sở dữ liệu.

Để tránh các vấn đề về hiệu suất, hãy đảm bảo rằng ứng dụng của bạn kiểm tra các chỉ mục khi khởi động bằng phương thức getIndexes () hoặc phương thức tương đương cho trình điều khiển của bạn và chấm dứt nếu các chỉ mục thích hợp không tồn tại. Luôn xây dựng chỉ mục trong các phiên bản sản xuất bằng cách sử dụng mã ứng dụng riêng biệt, trong thời gian bảo trì được chỉ định.

Tất nhiên, nó thực sự phụ thuộc vào cách ứng dụng của bạn được cấu trúc và triển khai. Ví dụ: nếu bạn đang triển khai Heroku và bạn không sử dụng tính năng khởi động trước của Heroku , thì có khả năng ứng dụng của bạn không phục vụ các yêu cầu trong quá trình khởi động và vì vậy có thể an toàn để tạo chỉ mục vào thời điểm đó.

Ngoài ra, từ câu trả lời được chấp nhận:

Vì vậy, nó chỉ ảnh hưởng đến hiệu suất khi bạn lần đầu tiên tạo chỉ mục và tại thời điểm đó các bộ sưu tập thường trống nên dù sao thì việc tạo chỉ mục cũng sẽ nhanh chóng.

Nếu bạn đã quản lý để có được mô hình dữ liệu và các truy vấn của mình ngay từ lần đầu tiên, điều này là tốt và thường là trường hợp này. Tuy nhiên, nếu bạn đang thêm chức năng mới vào ứng dụng của mình, với truy vấn DB mới trên một thuộc tính không có chỉ mục, bạn thường thấy mình đang thêm chỉ mục vào một bộ sưu tập chứa nhiều tài liệu hiện có.

Đây là lúc bạn cần phải cẩn thận về việc thêm các chỉ mục và xem xét cẩn thận các tác động của việc làm đó. Ví dụ: bạn có thể tạo chỉ mục trong nền :

db.ensureIndex({ name: 1 }, { background: true });

3
Được, vì vậy tất cả những gì bạn phải làm là KHÔNG khởi động máy chủ của bạn cho đến khi tất cả các lệnh gọi lại ensureIndex đã kích hoạt cho mỗi bộ sưu tập.
Alexander Mills

@AlexMills làm thế nào để bạn đảm bảo điều đó?
alonemo

async.each (Object.keys (models), function (key, cb) {models [key] .ensureIndexes (cb)}, cb)
Alexander Mills

chỉ cần gọi ensureIndexes trên mỗi mô hình mongoose, đợi tất cả kết thúc, sau đó khởi động máy chủ của bạn; Tôi cũng khuyên bạn nên chờ đợi cho các kết nối db xảy ra trước khi bắt đầu máy chủ của bạn cũng
Alexander Mills

2
Không ensureIndexcòn nữa. Có createIndexthay vào đó. Tôi nói đúng chứ?
jack trống

1

sử dụng mã khối này để xử lý chế độ sản xuất:

const autoIndex = process.env.NODE_ENV !== 'production';
mongoose.connect('mongodb://localhost/collection', { autoIndex });
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.