我正在使用Google Spreadsheet API更新包含大量数据的电子表格(数百行和大约20列)。
我已经测试了批量调用以更新2500个单元格。该呼叫大约需要40秒才能完成,请求大约为1mb,响应大约为2mb。
有没有办法让它更快地运作?
答案 0 :(得分:11)
通过在UPDATE之前跳过QUERY部分,我能够加快官方API http://code.google.com/apis/spreadsheets/data/3.0/developers_guide.html#SendingBatchRequests中提供的批处理请求。所以这就是他们在示例中所拥有的:
// Prepare the update
// getCellEntryMap is what makes the update fast.
Map cellEntries = getCellEntryMap(ssSvc, cellFeedUrl, cellAddrs);
CellFeed batchRequest = new CellFeed();
for (CellAddress cellAddr : cellAddrs) {
URL entryUrl = new URL(cellFeedUrl.toString() + "/" + cellAddr.idString);
CellEntry batchEntry = new CellEntry(cellEntries.get(cellAddr.idString));
batchEntry.changeInputValueLocal(cellAddr.idString);
BatchUtils.setBatchId(batchEntry, cellAddr.idString);
BatchUtils.setBatchOperationType(batchEntry, BatchOperationType.UPDATE);
batchRequest.getEntries().add(batchEntry);
}
// Submit the update
Link batchLink = cellFeed.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM);
CellFeed batchResponse = ssSvc.batch(new URL(batchLink.getHref()), batchRequest);
这就是我改为
的原因CellFeed batchRequest = new CellFeed();
for (CellInfo cellAddr : cellsInfo) {
CellEntry batchEntry = new CellEntry(cellAddr.row, cellAddr.col, cellAddr.idString);
batchEntry.setId(String.format("%s/%s", worksheet.getCellFeedUrl().toString(), cellAddr.idString));
BatchUtils.setBatchId(batchEntry, cellAddr.idString);
BatchUtils.setBatchOperationType(batchEntry, BatchOperationType.UPDATE);
batchRequest.getEntries().add(batchEntry);
}
CellFeed cellFeed = ssSvc.getFeed(worksheet.getCellFeedUrl(), CellFeed.class);
Link batchLink = cellFeed.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM);
ssSvc.setHeader("If-Match", "*");
CellFeed batchResponse = ssSvc.batch(new URL(batchLink.getHref()), batchRequest);
ssSvc.setHeader("If-Match", null);
请注意,应更改标题以使其正常工作。
答案 1 :(得分:2)
加速:由David Tolioupov发布 - 它有效。一些有用的额外信息。
如何使用CellFeed的示例,请参阅CellDemo.java http://gdata-java-client.googlecode.com/svn-history/r51/trunk/java/sample/spreadsheet/cell/CellDemo.java
该示例包含详细信息,足以帮助我优化代码。
如David Tolioupov所述,以这种方式创建CellEntry:
CellEntry batchEntry = new CellEntry(cellAddr.row, cellAddr.col, cellAddr.idString);
batchEntry.setId(String.format("%s/%s", cellFeedUrl.toString(), cellAddr.idString));
来自示例:
/**
* Returns a CellEntry with batch id and operation type that will tell the
* server to update the specified cell with the given value. The entry is
* fetched from the server in order to get the current edit link (for
* optimistic concurrency).
*
* @param row the row number of the cell to operate on
* @param col the column number of the cell to operate on
* @param value the value to set in case of an update the cell to operate on
*
* @throws ServiceException when the request causes an error in the Google
* Spreadsheets service.
* @throws IOException when an error occurs in communication with the Google
* Spreadsheets service.
*/
private CellEntry createUpdateOperation(int row, int col, String value)
throws ServiceException, IOException {
String batchId = "R" + row + "C" + col;
URL entryUrl = new URL(cellFeedUrl.toString() + "/" + batchId);
CellEntry entry = service.getEntry(entryUrl, CellEntry.class);
entry.changeInputValueLocal(value);
BatchUtils.setBatchId(entry, batchId);
BatchUtils.setBatchOperationType(entry, BatchOperationType.UPDATE);
return entry;
}
所需要的只是cellFeedUrl,然后创建请求并发送它。
答案 2 :(得分:1)
如果您要更新整行,可以尝试使用基于列表的Feed:
http://code.google.com/intl/fr-FR/apis/spreadsheets/data/3.0/developers_guide.html#UpdatingListRows
它允许您更新值(而不是公式)。
如果您仍然遇到性能问题,则应切换到关系数据库服务器或Google数据存储区(如果您使用的是谷歌应用引擎)