【问题标题】:Executing multiple Sparql Queries with QueryExecutionFactory at once一次使用 QueryExecutionFactory 执行多个 Sparql 查询
【发布时间】:2023-04-06 13:06:01
【问题描述】:

我必须一次执行大约 2000 个 sparql 查询。我目前正在一次执行一个查询。每个大约需要0.3s。因此,要执行所有查询,我们需要大约 600 秒。这是我用于查询执行的代码

QueryExecution qExec = QueryExecutionFactory.sparqlService("http://dbpedia.org/sparql", query.asQuery());
//query is a ParameterizedSparqlString which returns Query object
ResultSet resultSet = qExec.execSelect();

上面的代码在一个循环中。循环运行2000次,代码执行2000次。

所以,我想减少运行 2000 个查询所花费的时间

我在想如果我可以一次执行多个查询,例如执行多个 sql 语句的批处理插入,那么我可以减少花费的时间。有什么办法可以吗?

或者任何减少时间的可能解决方案对我来说都是救命稻草。

【问题讨论】:

  • SPARQL 中没有批处理的概念。您可以通过纯 Java 线程并行运行所有查询。 ExecutorService 是要走的路。
  • 注意,鉴于公共 DBpedia 服务是共享介质并且泛滥它可能会暂时阻止您的 IP,我很确定您在并行发送太多查询时可能会遇到麻烦 - 这是有道理的,否则,机器人可以轻松地关闭服务。如果您非常需要 DBpedia,请将其加载到本地三重存储并使用这个。
  • 您可能会受益于您自己的云端 DBpedia 镜像(2016-10 Snapshot, matching dbpedia.org/sparqlDBpedia-Live, matching live.dbpedia.org/sparql),您可以对 SPARQL 端点进行较少限制的配置,通过 JDBC 和 SPASQL 进行查询(SPARQL-in -SQL),和/或使用比公共实例更强大的实例类型。
  • @AKSW 我使用 executorservice 来处理 Java 线程中的所有查询。工作得很好。谢谢。

标签: java performance sparql jena dbpedia


【解决方案1】:

我找到了一个对我有用的解决方案。 首先我创建了一个可调用类

public class SparqlQueryCallable implements Callable<Model> {
    public static final String DBPEDIA_REPO = "http://dbpedia.org/sparql";
    private ParameterizedSparqlString query = new ParameterizedSparqlString();
    @Override
    public Model call() throws Exception {
        QueryExecution qExec = QueryExecutionFactory.sparqlService(DBPEDIA_REPO, this.query.asQuery());
        Model tempConstruct = qExec.execConstruct();
        return tempConstruct;
    }
}

然后在循环中我创建了所有可调用对象

List<SparqlQueryCallable> callable_list = new ArrayList<SparqlQueryCallable>();
for(ParameterizedSparqlString param_string: param_strings) {
    callable_list.add(new SparqlQueryCallable(param_string));
}

终于执行了

List<Future<Model>> futures = executorService.invokeAll(callable_list);

大大缩短了时间。

【讨论】: