2011-08-26 19 views
10

Im chạy một truy vấn và nó đang trở về 1400 kết quả và vì điều này tôi nhận được cảnh báo sau đây trong file log:Đối với Google App Engine (java), làm cách nào để đặt và sử dụng kích thước chunk trong FetchOptions?

com.google.appengine.api.datastore.QueryResultsSourceImpl logChunkSizeWarning: Truy vấn này không có kích thước chunk được đặt trong Tìm nạp và đã trả về hơn 1000 kết quả. Nếu tập hợp kết quả là kích thước này là phổ biến cho truy vấn này, hãy xem xét đặt kích thước chunk thành cải thiện hiệu suất.

Tôi không thể tìm thấy bất kỳ ví dụ nào về cách thực sự triển khai, có câu hỏi ở đây về python, nhưng khi sử dụng java và không hiểu python, tôi đang cố gắng dịch nó. Ngoài ra, truy vấn này (dưới đây) là 17226cpu_ms để thực thi, cảm giác như quá dài, tôi thậm chí không thể tưởng tượng điều gì sẽ xảy ra nếu tôi đã nói 5000 địa chỉ liên hệ và cần tìm kiếm thông qua chúng ở phía khách hàng (như bạn làm ! với địa chỉ liên lạc googlemail)

mã tôi có là:

int index=0; 
    int numcontacts=0; 
    String[][] DetailList; 

    PersistenceManager pm = PMF.get().getPersistenceManager(); 


    try { 
     Query query = pm.newQuery(Contact.class, "AdminID == AID"); 
     query.declareParameters("Long AID"); 
     query.setOrdering("Name asc"); 
     List<Contact> Contacts = (List<Contact>) query.execute(AdminID); 
     numcontacts=Contacts.size(); 
     DetailList=new String[numcontacts][5]; 

     for (Contact contact : Contacts) 
     { 
      DetailList[index][0]=contact.getID().toString(); 
      DetailList[index][1]=Encode.EncodeString(contact.getName()); 
      index++; 
     } 
    } finally { 
     pm.close(); 
    } 
    return (DetailList); 

tôi thấy hai mục sau trên đây:

nhưng không thực sự đi vào bất kỳ chi tiết về làm thế nào để thực hiện hoặc sử dụng các tùy chọn này. Tôi đoán nó là một tiến trình phía máy chủ, và tôi đoán rằng bạn có ý định thiết lập một loại vòng lặp nào đó để lấy từng đoạn một, nhưng làm cách nào để thực sự làm điều đó?

  • Tôi có thể gọi truy vấn trong vòng lặp không?
  • Làm cách nào để biết số lần lặp lại?
  • Tôi chỉ cần kiểm tra đoạn đầu tiên quay trở lại với số lượng nhỏ hơn số lượng mục nhập không?

Tôi muốn tìm hiểu những thứ như thế này mà không cần ví dụ thực tế để làm theo? Dường như với tôi rằng những người khác ở đây dường như "chỉ biết" làm thế nào để làm điều đó ..!

Xin lỗi Nếu tôi không hỏi những câu hỏi đúng cách hoặc tôi chỉ là một người mới làm mờ về điều này, nhưng tôi không biết nơi khác để chuyển sang con số này ra!

Trả lời

4

Đáp ứng cùng một vấn đề và nhận xét cuối cùng là từ một tháng trước, vì vậy, đây là những gì tôi đã tìm hiểu về truy vấn tập dữ liệu nặng.

Tôi đoán tôi sẽ sử dụng "Truy vấn con trỏ" kỹ thuật sau khi đọc những dòng trong docs google article (một trong python đề cập bằng cách này):

Bài viết này được viết cho phiên bản SDK 1.1.7. Kể từ phiên bản 1.3.1, con trỏ truy vấn (Java | Python) đã thay thế các kỹ thuật được mô tả bên dưới và hiện là phương pháp được khuyến nghị để phân trang qua các bộ dữ liệu lớn.

Trong tài liệu google về "Query Cursor". Dòng đầu tiên của doc cho chính xác lý do tại sao nhu cầu con trỏ:

con trỏ Query cho phép một ứng dụng để thực hiện một truy vấn và lấy một lô kết quả, sau đó lấy kết quả bổ sung cho cùng một truy vấn trong một trang web tiếp theo yêu cầu mà không phải trả phí truy vấn.

Tài liệu cũng cung cấp ví dụ java java của servlet bằng kỹ thuật con trỏ. Có một mẹo làm thế nào để tạo ra một con trỏ an toàn cho khách hàng. Cuối cùng, giới hạn của con trỏ được hiển thị.

Hy vọng điều này sẽ mang lại cho bạn một hướng dẫn để giải quyết vấn đề của bạn.

nhắc nhỏ về phạm vi và bù đắp, khá ảnh hưởng đến hiệu suất nếu quên (và tôi đã làm ^^):

Các offset bắt đầu có tác động đối với hiệu suất: Datastore phải lấy và sau đó loại bỏ tất cả kết quả trước khi bắt đầu bù đắp . Ví dụ: truy vấn có phạm vi 5, 10 tìm nạp 10 kết quả từ Datastore, sau đó loại bỏ năm đầu tiên và trả về số còn lại là năm cho ứng dụng.


Edit: Như làm việc với JDO, tôi vẫn tiếp tục tìm kiếm một cách để cho phép mã trước đây của tôi để tải hơn 1000 kết quả trong một truy vấn duy nhất. Vì vậy, nếu bạn đang sử dụng JDO quá, tôi thấy điều này cũ issue:

Query query = pm.newQuery(...); 
// I would use of value below 1000 (gae limit) 
query.getFetchPlan().setFetchSize(numberOfRecordByFetch); 
3

Đây là cách tôi áp dụng FetchOptions, so với mã ví dụ của bạn, bạn có thể cần phải tinh chỉnh một chút:

// ..... build the Query object 
FetchOptions fetch_options = 
    FetchOptions.Builder.withPrefetchSize(100).chunkSize(100); 
QueryResultList<Entity> returned_entities = 
    datastore_service_instance.prepare(query).asQueryResultList(fetch_options); 

Tất nhiên rằng những con số có thể thay đổi (100).

Nếu câu trả lời của tôi không phải là những gì bạn đang tìm kiếm thì bạn có thể lặp lại câu hỏi của mình (chỉnh sửa).

Nhân tiện tôi là người đã viết câu hỏi được liên kết đầu tiên.

+0

Tôi không chắc chắn cách diễn đạt lại câu hỏi của mình, vì vậy Im sẽ trả lời nhận xét của bạn. Tôi có nghĩa là chỉ cần thay thế một dòng mã của tôi: "Danh sách Liên hệ = (Danh sách ) query.execute (AdminID);" với hai dòng mã của bạn? Nếu vậy bạn có thể giúp tôi bằng cách thay đổi mã của bạn để phù hợp với các biến trong tôi?vì tôi không thể làm được. Tôi đã thử khoảng 20 sự kết hợp của các biến của tôi nhưng không có ý nghĩa gì cả, đó là lý do tại sao tôi hỏi những câu hỏi trên ... Một điều tôi đã nhấn một vài lần dường như liên quan đến thực tế là "Truy vấn của tôi" "ở trên được nhập dưới dạng" javax.jdo.Query; " – johnvdenley

+0

Bất cứ ai có thể giúp tôi với điều này như bây giờ của nó gây ra cho tôi một vấn đề tôi không thể workaround nữa! – johnvdenley

1

Nếu bạn đang sử dụng kho dữ liệu trực tiếp, mà không JDO, sau đó bạn sẽ làm điều gì đó như sau để thiết lập các đoạn kích thước khi bạn đang lặp qua dữ liệu:

Query query = new Query("entityname"); 
PreparedQuery preparedQuery = dataStore.prepare(query); 
// the 200 should be less than 1000 
FetchOptions options = FetchOptions.Builder.withChunkSize(200); 
for (Entity result : preparedQuery.asIterable(options)) { 
    ... 
} 
+0

Tôi ghét phải nói điều đó, nhưng tôi chưa bao giờ tìm ra cách để làm điều này, tôi chỉ có một khách hàng gọi đến để nói rằng vấn đề này đã khiến đầu của nó trở nên xấu xí trở lại ... Họ đang thu thập 2044 bản ghi dữ liệu từ App engine và tôi lại gặp lỗi để thiết lập kích thước chunk để tránh vấn đề ... Về cơ bản, tôi nhận được thời gian chờ tải dữ liệu và vẫn không thực sự hiểu cách giải quyết vấn đề, đối với tôi, bit "..." trong vòng lặp của bạn ở trên mà tôi không biết cách xử lý. Kho dữ liệu có trả lại kết quả trong 200 khối, sau đó tôi kết hợp lại chúng trước khi gửi chúng cho khách hàng? – johnvdenley

+0

Có, tôi sẽ kết hợp lại chúng @johnvdenley. Bạn đang phá vỡ truy vấn để nó kết thúc nhanh hơn và sau đó kết hợp các kết quả để bằng toàn bộ danh sách. – Gray

Các vấn đề liên quan