Tổng quan về chỉ mục

Phần này mô tả cách lập chỉ mục cho phiên bản Firestore Enterprise. Phiên bản Firestore Enterprise không tạo bất kỳ chỉ mục nào theo mặc định. Để giảm chi phí và cải thiện hiệu suất cơ sở dữ liệu, hãy tạo chỉ mục cho các truy vấn thường dùng nhất.

Chỉ mục có tác động lớn đến hiệu suất của cơ sở dữ liệu. Nếu có chỉ mục cho một truy vấn, thì cơ sở dữ liệu có thể trả về kết quả một cách hiệu quả bằng cách giảm lượng dữ liệu cần quét và giảm công việc cần thiết để sắp xếp kết quả. Tuy nhiên, các mục nhập chỉ mục sẽ làm tăng chi phí lưu trữ và khối lượng công việc được thực hiện trong một thao tác ghi trên các trường được lập chỉ mục.

Định nghĩa và cấu trúc chỉ mục

Một chỉ mục bao gồm:

  • mã nhận dạng bộ sưu tập
  • danh sách các trường trong tập hợp đã cho
  • chế độ chỉ mục (tăng dần, giảm dần hoặc chứa mảng) cho mỗi trường

Chỉ mục cũng có thể bật các tuỳ chọn sparse (thưa thớt) hoặc unique (duy nhất).

Thứ tự chỉ mục

Thứ tự và hướng sắp xếp của mỗi trường xác định duy nhất chỉ mục. Ví dụ: hai chỉ mục sau đây là hai chỉ mục riêng biệt và không thể thay thế cho nhau:

Thu thập Trường
thành phố quốc gia (tăng dần), dân số (giảm dần)
thành phố dân số (giảm dần), quốc gia (tăng dần),

Khi tạo chỉ mục để hỗ trợ một truy vấn, hãy thêm các trường theo cùng thứ tự với truy vấn của bạn.

Mật độ chỉ mục

Theo mặc định, các mục nhập chỉ mục lưu trữ dữ liệu từ tất cả tài liệu trong một tập hợp. Đây được gọi là chỉ mục không thưa. Mục nhập chỉ mục sẽ được thêm cho một tài liệu bất kể tài liệu đó có chứa bất kỳ trường nào được chỉ định trong chỉ mục hay không. Các trường không tồn tại được coi là có giá trị NULL khi tạo mục nhập chỉ mục. Để thay đổi hành vi này, bạn có thể xác định chỉ mục là chỉ mục thưa.

Chỉ mục thưa thớt

Chỉ mục thưa chỉ lập chỉ mục các tài liệu trong tập hợp chứa giá trị (bao gồm cả giá trị rỗng) cho ít nhất một trong các trường được lập chỉ mục. Chỉ mục thưa giúp giảm chi phí lưu trữ và có thể cải thiện hiệu suất.

Chỉ mục Array-contains

Để tối ưu hoá hiệu suất truy vấn khi truy vấn một trường mảng bằng array-contains hoặc array-contains-any, bạn có thể lập chỉ mục trường đó ở chế độ array-contains. Một chỉ mục có thể có tối đa một trường ở chế độ array-contains.

Bằng cách lập chỉ mục một trường mảng ở chế độ array-contains, công cụ truy vấn có thể nhanh chóng tìm thấy các tài liệu chứa giá trị mảng cụ thể. Nếu không có chỉ mục, các truy vấn sẽ kiểm tra giá trị mảng bằng cách quét toàn bộ tập hợp, điều này làm tăng độ trễ truy vấn và chi phí đọc khi kích thước của tập hợp tăng lên.

Để lập chỉ mục một trường mảng, trường đó phải đáp ứng yêu cầu sau:

  • Yêu cầu về mảng không trống: Mục nhập chỉ mục chỉ được tạo nếu trường mảng tồn tại trong tài liệu và là một mảng không trống. Những tài liệu thiếu trường mảng, có trường không phải mảng hoặc có trường mảng trống sẽ không được lập chỉ mục.

Mối liên hệ giữa mật độ và chỉ mục array-contains

Đối với các chỉ mục có trường array-contains, quy tắc mật độ chỉ mục chỉ áp dụng cho các trường được lập chỉ mục theo thứ tự. Nếu yêu cầu về mảng không trống được đáp ứng, thì các quy tắc về mật độ sẽ áp dụng cho các trường được lập chỉ mục còn lại trong chỉ mục:

  • Chỉ mục không thưa (DENSE): Một mục chỉ mục được tạo cho tài liệu. Mọi trường được lập chỉ mục theo thứ tự bị thiếu trong chỉ mục đều được lưu trữ dưới dạng null trong mục nhập chỉ mục.
  • Chỉ mục thưa (SPARSE): Mục nhập chỉ mục chỉ được tạo nếu có ít nhất một trong các trường được lập chỉ mục theo thứ tự tồn tại trong tài liệu.

Ví dụ: Tạo mục nhập chỉ mục

Hãy xem xét chỉ mục users (tags[*], status ASC):

Tài liệu Chỉ số NON-SPARSE Chỉ số SPARSE
{
  tags: ["news"],
  status: "active"
}
Đã lập chỉ mục:
• (thẻ: "news", trạng thái: "active")
Đã lập chỉ mục:
• (thẻ: "news", trạng thái: "active")
{
  tags: ["news", "sports"],
  status: "active"
}
Đã lập chỉ mục:
• (thẻ: "news", trạng thái: "active")
• (thẻ: "sports", trạng thái: "active")
Đã lập chỉ mục:
• (thẻ: "news", trạng thái: "active")
• (thẻ: "sports", trạng thái: "active")
{
  tags: ["news", "news"],
  status: "active"
}
Đã lập chỉ mục:
• (thẻ: "news", trạng thái: "active") (đã loại bỏ trùng lặp)
Đã lập chỉ mục:
• (thẻ: "news", trạng thái: "active") (đã loại bỏ trùng lặp)
{
  tags: [null],
  status: "active"
}
Đã lập chỉ mục:
• (thẻ: null, trạng thái: "active")
Đã lập chỉ mục:
• (thẻ: null, trạng thái: "active")
{
  tags: ["news"]
}
Đã lập chỉ mục:
• (thẻ: "news", trạng thái: null)
Chưa được lập chỉ mục (thiếu trường status)
{
  tags: "news",
  status: "active"
}
Không được lập chỉ mục (trường không phải là một mảng) Không được lập chỉ mục (trường không phải là một mảng)
{
  tags: null,
  status: "active"
}
Không được lập chỉ mục (trường không phải là một mảng) Không được lập chỉ mục (trường không phải là một mảng)
{
  status: "active"
}
Chưa được lập chỉ mục (thiếu trường tags) Chưa được lập chỉ mục (thiếu trường tags)
{
  tags: [],
  status: "active"
}
Chưa được lập chỉ mục (mảng trống) Chưa được lập chỉ mục (mảng trống)

Ví dụ về truy vấn

Web
// Query for users where 'tags' contains 'news' and 'status' is 'active'
const query = db.collection("users")
  .where("tags", "array-contains", "news")
  .where("status", "==", "active");

// Documents returned by the query:
// [
//   {
//     "id": "alice",
//     "tags": ["news", "tech"],
//     "status": "active"
//   }
// ]

Chỉ mục duy nhất

Đặt tuỳ chọn chỉ mục duy nhất để thực thi các giá trị duy nhất cho các trường được lập chỉ mục. Đối với chỉ mục trên nhiều trường, mỗi tổ hợp giá trị phải là duy nhất trên toàn bộ chỉ mục. Cơ sở dữ liệu từ chối mọi thao tác cập nhật và chèn cố gắng tạo các mục nhập chỉ mục có giá trị trùng lặp. Nếu dữ liệu của các trường được lập chỉ mục chứa các giá trị trùng lặp và bạn cố gắng tạo một chỉ mục duy nhất, thì quá trình tạo chỉ mục sẽ không thành công và xuất hiện thông báo lỗi trong thông tin chi tiết về thao tác.

Các trường bị thiếu trong một chỉ mục duy nhất

Nếu bạn chèn một tài liệu thiếu các trường cho chỉ mục duy nhất, thì chỉ mục này sẽ đặt giá trị null cho các trường bị thiếu. Mục nhập chỉ mục thu được phải là duy nhất, nếu không thì thao tác sẽ không thành công.

Ví dụ: với chỉ mục này:

Thu thập Số trường được lập chỉ mục Phạm vi truy vấn
thành phố tên (tăng dần) Thu thập

Nếu bạn thêm tài liệu {"abbreviation": "LA"} vào tập hợp, thì chỉ mục duy nhất sẽ tạo một mục nhập có name được đặt thành null. Nếu sau đó bạn cố gắng thêm tài liệu {"abbreviation": "NYC"}, thao tác này sẽ không thành công vì mục nhập kết quả cho chỉ mục duy nhất là giống nhau.

Hành vi tương tự cũng áp dụng cho các chỉ mục duy nhất có nhiều trường. Khi tạo hoặc cập nhật tài liệu, các trường được lập chỉ mục bị thiếu sẽ được đặt thành null và mục nhập chỉ mục thu được phải là duy nhất trong chỉ mục.

Chỉ mục duy nhất trên các giá trị mảng

Chỉ mục array-contains duy nhất cấm các tài liệu có phần tử mảng trùng lặp.

Loại chỉ mục này không bắt buộc một mảng phải có các giá trị riêng biệt trong một tài liệu.

Ví dụ: với một chỉ mục duy nhất trên trường có tên là tags:

Bạn có thể chèn tài liệu sau đây (doc1):

{
  "tags": [ "news", "tech", "news", "music" ]
}

Chỉ mục cho phép các giá trị trùng lặp ("news") trong cùng một mảng của một tài liệu.

Nếu bạn cố gắng chèn tài liệu thứ hai, doc2, có phần tử trùng lặp, thao tác sẽ không thành công:

{
  "tags": [ "sports", "music" ]
}

Thao tác không thành công vì "music" đã có trong mảng của doc1 và được liên kết trong chỉ mục.

Nếu bạn cần đảm bảo rằng các phần tử trong cùng một mảng trong một tài liệu là duy nhất, hãy xử lý việc này trong logic ứng dụng của bạn.

Mảng trống, trường bị thiếu và giá trị rỗng

Thông thường, các trường bị thiếu trong một chỉ mục duy nhất được coi là null và phải là duy nhất trên các tài liệu (xem phần Trường vắng mặt trong một chỉ mục duy nhất). Tuy nhiên, đối với các chỉ mục duy nhất trên các trường mảng:

  • Mảng trống, trường bị thiếu và giá trị rỗng độc lập: Nếu trường mảng trống, thiếu hoàn toàn hoặc chứa giá trị null độc lập (không nằm trong mảng), thì hệ thống sẽ không tạo khoá chỉ mục cho tài liệu. Do đó, nhiều tài liệu có thể có các trường trống hoặc giá trị null độc lập mà không gây ra lỗi khoá trùng lặp.
  • Phần tử rỗng bên trong một mảng: Nếu mảng chứa giá trị null dưới dạng một phần tử (ví dụ: ["news", null]), thì phần tử null sẽ được lập chỉ mục. Bất kỳ tài liệu nào tiếp theo có chứa phần tử null trong trường mảng được lập chỉ mục sẽ không thành công và gặp lỗi khoá trùng lặp.

Khắc phục sự cố tạo chỉ mục

Bạn có thể gặp lỗi khi tạo chỉ mục trong quá trình quản lý chỉ mục. Thao tác lập chỉ mục có thể không thành công nếu cơ sở dữ liệu gặp vấn đề với dữ liệu. Thao tác lập chỉ mục có thể không thành công vì những lý do sau:

  • Bạn đã đạt đến giới hạn lập chỉ mục. Ví dụ: thao tác có thể đã đạt đến số lượng mục nhập chỉ mục tối đa cho mỗi tài liệu. Nếu quá trình tạo chỉ mục không thành công, bạn sẽ thấy thông báo lỗi. Nếu bạn chưa đạt đến giới hạn chỉ mục, hãy thử lại thao tác lập chỉ mục.
  • Bạn đặt tuỳ chọn chỉ mục duy nhất và dữ liệu của các trường được lập chỉ mục sẽ tạo các mục chỉ mục trùng lặp. Để tiếp tục, hãy xoá các tổ hợp giá trị trùng lặp khỏi dữ liệu.

Bước tiếp theo

Tìm hiểu cách tạo và quản lý chỉ mục.