【问题标题】:How to add more quickly add 1 million triples in Sesame 2.7.7Sesame 2.7.7如何更快地添加100万个三元组
【发布时间】:2013-11-05 07:07:50
【问题描述】:

我注意到,使用 RepositoryConnection 方法 add 进行实例化比使用 SPARQL 查询修改模型进行实例化要慢。尽管存在差异,但即使是 SPARQL 更新方法也需要很长时间来实例化(3.4 分钟到 10,000 个三元组)。多个inserts(每个三元组一个查询)或一个大insert 查询的执行不会改变方法的性能。它仍然很慢。是否有其他适合添加 100 万个三元组的方法,或者有什么特殊配置可以提供帮助?

RepositoryConnection 代码

Repository myRepository = new HTTPRepository(serverURL, repositoryId);
myRepository.initialize();
RepositoryConnection con = myRepository.getConnection();
ValueFactory f = myRepository.getValueFactory();

i = 0;
j = 1000000;    

while(i < j)(
    URI event    = f.createURI(ontologyIRI + "event"+i);
    URI hasTimeStamp    = f.createURI(ontologyIRI + "hasTimeStamp");
    Literal timestamp   = f.createLiteral(fields.get(0));
    con.add(event, hasTimeStamp, timestamp);
    i++
}    

SPARQL 代码

Repository myRepository = new HTTPRepository(serverURL, repositoryId);
myRepository.initialize();
RepositoryConnection con = myRepository.getConnection();

i = 0;
j = 1000000;    

while(i < j)(
    query = "INSERT {";
    query += "st:event"+i+" st:hasTimeStamp     '"+fields.get(0)+"'^^<http://www.w3.org/2001/XMLSchema#float> .\n"
    + "}"
      + "WHERE { ?x ?y ?z }";
    Update update = con.prepareUpdate(QueryLanguage.SPARQL, query);
    update.execute();

    i++;
}

版本 我已经对 In MemoryNative Store Sesame 存储库进行了实验,同步值等于 0

【问题讨论】:

  • 您已经谈到了后端存储是什么或它的配置。 Sesame 是一个支持各种存储后端的框架,例如本机和磁盘以及 OWLIM 等第三方后端。使用的后端及其配置可能是这里的一个重要因素。
  • 按照它的写法,这个问题可能与 Stack Overflow 无关,因为它要求“对 Sesame 在实例化 RDF 三元组时的性能的看法”和“寻找最合适的方法”,但是“许多好的问题会根据专家的经验产生一定程度的意见,但这个问题的答案往往几乎完全基于意见,而不是事实、参考资料或特定的专业知识。”也就是说,你在这里有一段特定的代码,并且有一些关于性能的数字,所以它可能是可以回答的。您需要提供更多信息……
  • 您为使用 RepositoryConnection.add 显示的代码仅插入一个三元组,因此我不确定您如何得出多个三元组的插入速度很慢的结论。可以这么说,如果您需要 3.4 分钟来插入 10,000 个三元组,那么您就做错了(或者您的硬件非常有限,或者后端配置不适合快速更新)。您需要更准确地了解您正在尝试做什么以及您是如何做的(例如,您是否正确使用了 Sesame 的事务机制?)
  • 另外:您显示的代码 sn-ps 不完整。由于您在多个地方使用了变量i,我怀疑您在实际代码中的某处有一个循环。为了能够回答您做错了什么,您需要显示该循环。

标签: java rdf sparql sesame


【解决方案1】:

(我只是注意到您添加了请求的附加信息,因此回复比较晚)

正如我所怀疑的那样,问题在于您没有使用事务将更新操作一起批处理。实际上,您执行的每个添加操作都变成了一个事务(默认情况下,芝麻存储库连接以自动提交模式运行),这既慢又低效。

要改变这一点,启动一个事务(使用RepositoryConnection.begin()),然后添加你的数据,最后调用RepositoryConnection.commit() 来完成事务。

您应该如何修改您的第一个代码示例:

Repository myRepository = new HTTPRepository(serverURL, repositoryId);   
myRepository.initialize(); 
RepositoryConnection con = myRepository.getConnection(); 
ValueFactory f = myRepository.getValueFactory();

i = 0; 
j = 1000000;    

try {
  con.begin(); // start the transaction
  while(i < j) {
      URI event    = f.createURI(ontologyIRI + "event"+i);
      URI hasTimeStamp    = f.createURI(ontologyIRI + "hasTimeStamp");
      Literal timestamp   = f.createLiteral(fields.get(0));
      con.add(event, hasTimeStamp, timestamp);
      i++; 
  }
  con.commit(); // finish the transaction: commit all our adds in one go.
}
finally {
  // always close the connection when you're done with it. 
  con.close();
}

这同样适用于带有 SPARQL 更新的代码。有关如何处理事务的更多信息,请查看 Sesame 手册,尤其是 the chapter about using the Repository API

顺便说一句:由于您是在 HTTP 上工作,因此如果您的事务变得太大,则存在一种风险,它会开始在您的客户端中消耗大量内存。如果这种情况开始发生,您可能希望将更新分解为多个事务。但是我认为,如果有一个包含一百万个三元组的更新,你应该还可以。

【讨论】:

    猜你喜欢
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    相关资源
    最近更新 更多