1

我正在做非常简单的查询

SELECT cmis:objectId, cmis:name, cmis:parentId
FROM cmis:folder
ORDER BY cmis:name

使用 apache cmis 工作台运行此查询需要 ~ 15 秒 使用 opencmis 运行相同的查询非常快,但执行结果非常慢 ~ 3 分钟。

session.query( queryStmt, false).iterator().toList()

通过像这样拆分呼叫

def rs = session.query( queryStmt, false)
def iterator = rs.iterator()
def folders = iterator.toList()

我能够确定这toList()是缓慢的地方。但我不明白为什么。

我还尝试定义一个 operationContext 并将其与查询一起使用。结果相同。这是我的操作上下文

def filter = "cmis:objectId,cmis:name,cmis:parentId"
def context = session.createOperationContext()
context.setCacheEnabled(false)
context.setFilterString(filter)
context.setRenditionFilterString(filter)

关于如何更快地执行此查询的任何想法?

4

2 回答 2

3

默认情况下,CMIS 工作台仅获取前 100 个命中。根据存储库,这通常很快。增加“最大命中”以获得更多。

要复制 CMIS 工作台正在执行的操作,请尝试以下代码片段:

String queryStmt = "SELECT cmis:objectId, cmis:name, cmis:parentId FROM cmis:folder ORDER BY cmis:name";
int maxHits = 100;

OperationContext context = session.createOperationContext();
context.setMaxItemsPerPage(maxHits);

session.query(queryStmt, false, context).getPage(maxHits).iterator().toList();

toList遍历查询的所有结果。默认的 OperationContext 定义了 100 个命中的批次。也就是说,在后台 OpenCMIS 将对存储库进行几次(可能很多)查询调用,要求前 100 次点击,第二次 100 次点击,第三次 100 次点击,...

如果您总共有 100 万次点击,那么您最终会收到相当多的后端调用。

尝试使用 增加批量大小context.setMaxItemsPerPage(1000000)。如果您有很多点击并希望它们全部作为列表,这通常会更快。

当您在循环中使用它们并且不需要一次全部使用它们时,小批量会更好。它还允许处理不适合客户端内存的结果集。

另一个方面:稍后在 Java 中摆脱ORDER BY和排序列表。无论如何,您的结果集都在内存中。如果存储库上没有索引cmis:name,它会减慢服务器端的查询处理速度。

于 2017-04-19T20:28:52.343 回答
0

感谢@Florian的帮助。

他解决了我的问题。

def context = session.createOperationContext()
context.includeAllowableActions = false
context.maxItemsPerPage = 15000
def folderList = session.query(getFoldersList, false, context).iterator().toList()

当然,在现实生活中,每页的最大项目数不应该是这样的任意数字。

于 2017-04-20T14:44:08.267 回答