Tối ưu hoá hiệu suất truy vấn

Để khắc phục sự cố truy vấn chậm, hãy sử dụng tính năng Giải thích truy vấn để lấy kế hoạch thực thi truy vấn và hồ sơ thực thi thời gian chạy. Phần sau đây mô tả các bước bạn có thể thực hiện để tối ưu hoá hiệu suất truy vấn tuỳ thuộc vào hồ sơ thực thi:

Giới hạn số lượng kết quả

Sử dụng trường bản ghi được trả về trong cây thực thi để xác định xem truy vấn có trả về nhiều tài liệu hay không. Hãy cân nhắc việc giới hạn số lượng tài liệu được trả về bằng cách sử dụng giai đoạn limit(...). Điều này giúp giảm kích thước byte được chuyển đổi tuần tự của kết quả khi trả về cho ứng dụng qua mạng. Trong trường hợp nút Limit đứng trước nút MajorSort, công cụ truy vấn có thể kết hợp nút Limit và nút MajorSort, đồng thời thay thế một cụ thể hoá và sắp xếp đầy đủ trong bộ nhớ bằng một sắp xếp TopN, giúp giảm yêu cầu về bộ nhớ cho truy vấn.

Giới hạn kích thước tài liệu kết quả

Hãy cân nhắc việc giới hạn kích thước của tài liệu được trả về bằng cách sử dụng select(...) để chỉ trả về các trường bắt buộc hoặc remove_fields(...) để loại bỏ các trường quá lớn. Điều này giúp giảm chi phí tính toán và bộ nhớ khi xử lý kết quả trung gian, cũng như kích thước byte được chuyển đổi tuần tự của kết quả khi trả về cho ứng dụng qua mạng. Trong trường hợp tất cả các trường được tham chiếu trong truy vấn đều được bao gồm trong một chỉ mục thông thường, thì điều này cũng cho phép truy vấn được bao gồm hoàn toàn trong quá trình quét chỉ mục, tránh việc phải tìm nạp tài liệu từ bộ nhớ chính.

Sử dụng chỉ mục

Hãy làm theo hướng dẫn sau để thiết lập và tối ưu hoá chỉ mục.

Xác định xem truy vấn có đang sử dụng chỉ mục hay không

Bạn có thể xác định xem truy vấn có đang sử dụng chỉ mục hay không bằng cách kiểm tra các nút lá trong cây thực thi. Nếu nút lá của cây thực thi là nút TableScan, thì tức là truy vấn không sử dụng chỉ mục và đang quét tài liệu từ bộ nhớ chính. Nếu một chỉ mục đang được sử dụng, nút lá của cây thực thi sẽ hiển thị mã nhận dạng chỉ mục và các trường chỉ mục của chỉ mục đó.

Xác định chỉ mục tốt hơn

Chỉ mục sẽ hữu ích cho một truy vấn nếu chỉ mục đó có thể giảm số lượng tài liệu mà công cụ truy vấn cần tìm nạp từ bộ nhớ chính hoặc nếu thứ tự trường của chỉ mục đó có thể đáp ứng yêu cầu Sắp xếp của truy vấn.

Nếu một chỉ mục được dùng cho một truy vấn, nhưng công cụ truy vấn vẫn đang tìm nạp và loại bỏ nhiều tài liệu (được xác định bằng một nút Quét trả về nhiều bản ghi, theo sau là một nút Bộ lọc trả về ít bản ghi), thì đây là dấu hiệu cho thấy vị từ truy vấn được đáp ứng bằng chỉ mục không có tính chọn lọc. Để tạo một chỉ mục phù hợp hơn, hãy xem bài viết Tạo chỉ mục.

Nếu một chỉ mục được dùng cho một truy vấn, nhưng công cụ truy vấn vẫn đang thực hiện việc sắp xếp lại tập kết quả trong bộ nhớ (được xác định bằng nút MajorSort trong cây thực thi truy vấn), thì đây là dấu hiệu cho thấy chỉ mục được dùng không thể đáp ứng yêu cầu Sắp xếp của truy vấn. Để tạo một chỉ mục phù hợp hơn, hãy xem phần tiếp theo.

Tạo chỉ mục

Làm theo tài liệu quản lý chỉ mục để tạo chỉ mục. Để đảm bảo truy vấn của bạn có thể sử dụng chỉ mục, hãy tạo chỉ mục thông thường (không phải Multikey) với các trường theo thứ tự sau:

  1. Tất cả các trường sẽ được dùng trong toán tử bằng. Để tối đa hoá cơ hội sử dụng lại trên các truy vấn, hãy sắp xếp các trường theo thứ tự giảm dần về tần suất xuất hiện của các trường trong toán tử bằng giữa các truy vấn.
  2. Tất cả các trường sẽ được sắp xếp (theo cùng một thứ tự).
  3. Các trường sẽ được dùng trong toán tử phạm vi hoặc bất đẳng thức theo thứ tự giảm dần của tính chọn lọc ràng buộc truy vấn.
  4. Các trường sẽ được trả về dưới dạng một phần của truy vấn trong chỉ mục: việc đưa các trường đó vào chỉ mục cho phép chỉ mục bao gồm truy vấn và tránh phải tìm nạp tài liệu từ bộ nhớ chính.

Buộc quét chỉ mục hoặc bảng

Khi bạn truy vấn Cloud Firestore, hệ thống sẽ tự động sử dụng mọi chỉ mục có khả năng giúp truy vấn hiệu quả hơn. Do đó, bạn không cần chỉ định chỉ mục cho các truy vấn của mình. Tuy nhiên, đối với những truy vấn quan trọng cho khối lượng công việc của bạn, bạn nên sử dụng tuỳ chọn forceIndex để có hiệu suất nhất quán hơn.

Trong một số ít trường hợp, Cloud Firestore có thể chọn một chỉ mục khiến độ trễ truy vấn tăng lên. Nếu đã làm theo các bước khắc phục sự cố về tình trạng sụt giảm hiệu suất và xác nhận rằng bạn nên thử một chỉ mục khác cho truy vấn, thì bạn có thể chỉ định chỉ mục bằng cách sử dụng tuỳ chọn forceIndex.

Bạn có thể sử dụng tuỳ chọn forceIndex trên bất kỳ giai đoạn đầu vào nào trong các thao tác của quy trình để ghi đè kế hoạch truy vấn mặc định của Cloud Firestore và chỉ định một chỉ mục để sử dụng hoặc buộc quét bảng.

Buộc một chỉ mục cụ thể

Để buộc truy vấn sử dụng một chỉ mục cụ thể, hãy cung cấp mã nhận dạng chỉ mục dưới dạng chuỗi cho tuỳ chọn forceIndex. Bạn có thể tìm mã chỉ mục trong bảng điều khiển hoặc trong thông báo lỗi.

Ví dụ sau đây buộc trình lập kế hoạch sử dụng chỉ mục có mã nhận dạng CICAgOi36pgK:

Node.js
// Force Planner to use Index ID CICAgOi36pgK
await db.pipeline()
  .collectionGroup({ collectionId: "customers", forceIndex: "CICAgOi36pgK" })
  .limit(100)
  .execute();
Java
// Force Planner to use Index ID CICAgOi36pgK
Pipeline.Snapshot results1 =
    firestore.pipeline()
      .collectionGroup("customers", new CollectionGroupOptions()
          .withHints(new CollectionHints().withForceIndex("CICAgOi36pgK")))
      .limit(100)
      .execute().get();
Bắt đầu
// Force Planner to use Index ID CICAgOi36pgK
snapshot1 := client.Pipeline().
	CollectionGroup("customers", firestore.WithForceIndex("CICAgOi36pgK")).
	Limit(100).
	Execute(ctx)

Dưới đây là một số trường hợp sử dụng để buộc một chỉ mục cụ thể:

  • Thử nghiệm hiệu suất của các chỉ mục khác nhau.
  • Đảm bảo một chỉ mục cụ thể, tối ưu đã biết được dùng cho một truy vấn.
  • Ghi đè trình tối ưu hoá khi lựa chọn mặc định của trình tối ưu hoá không tối ưu cho một truy vấn cụ thể.

Nếu không tìm thấy chỉ mục đã chỉ định, thì truy vấn sẽ không thành công.

Buộc quét bảng

Thao tác quét bảng sẽ đọc các tài liệu trong tập hợp hoặc nhóm tập hợp mà không sử dụng bất kỳ chỉ mục phụ nào. Để buộc quét bảng, hãy đặt forceIndex thành primary.

Ví dụ sau đây buộc phải quét bảng:

// Force Planner to only do a Full-Table Scan
db.pipeline()
  .collectionGroup({ collectionId: "customers", forceIndex: "primary" })
  .limit(100)

Bạn có thể sử dụng tính năng quét bảng trong các trường hợp sau:

  • Đối với các tập hợp rất nhỏ, nơi không cần đến mức hao tổn tài nguyên cho chỉ mục.
  • Đối với các truy vấn truy cập vào hầu hết tài liệu trong một tập hợp.
  • Để gỡ lỗi và so sánh hiệu suất.

Sử dụng forceIndex với tính năng Giải thích truy vấn

Bạn có thể sử dụng tính năng Giải thích truy vấn ở chế độ explain hoặc analyze để quan sát tác động của forceIndex:

  • Xác minh rằng Cloud Firestore đã sử dụng chỉ mục được chỉ định trong forceIndex bằng cách kiểm tra các nút lá của cây thực thi cho mã nhận dạng chỉ mục.
  • Xác nhận rằng nút TableScan xuất hiện trong kế hoạch khi sử dụng forceIndex: "primary".
  • Với chế độ analyze, hãy so sánh các chỉ số hiệu suất (chẳng hạn như độ trễ, số tài liệu được quét và số mục nhập chỉ mục được quét) khi có và không có forceIndex để tinh chỉnh hiệu suất truy vấn.

Các phương pháp hay nhất cho forceIndex

Mặc dù forceIndex cung cấp nhiều quyền kiểm soát hơn đối với việc thực thi truy vấn, nhưng trình tối ưu hoá truy vấn của Cloud Firestore thường hiệu quả cho hầu hết các trường hợp sử dụng. Hãy cân nhắc các phương pháp hay nhất sau đây khi sử dụng forceIndex:

  • Sử dụng forceIndex một cách hợp lý. Nếu bạn nhận thấy hiệu suất không tối ưu với kế hoạch truy vấn mặc định, hãy sử dụng tính năng Giải thích truy vấn để chẩn đoán vấn đề trước khi buộc sử dụng chỉ mục.
  • Khi sử dụng forceIndex, hãy nhớ kiểm thử các truy vấn của bạn bằng khối lượng dữ liệu thực tế để hiểu rõ các đặc điểm về hiệu suất và chi phí.
  • Tránh sử dụng forceIndex: "primary" trên các tập hợp lớn trong môi trường thực tế.

Để biết thêm thông tin về kết quả của một truy vấn được thực thi bằng tính năng Giải thích truy vấn, hãy xem phần Tài liệu tham khảo về việc thực thi truy vấn.