【问题标题】:BaseX - Out of memory when using enclosing xml in XQueryBaseX - 在 XQuery 中使用封闭 xml 时内存不足
【发布时间】:2017-08-21 10:17:20
【问题描述】:

我一直在尝试查询包含超过 1500000 个项目的 BaseX 数据库。 当我运行此查询时

for $item in collection('coll')//item
    return $item (: returns an xml element :)

它在不到一秒的时间内执行。

但是当我尝试以 xml 格式返回结果时,我收到“Out of main memory”错误。

<xml>{
    for $item in collection('coll')//item
       return $item
}</xml>

这让我想放弃原生 xml db 方法(其他数据库也一样,例如 eXistDB),所以如果有人知道这个问题的任何信息,那将非常有帮助。

谢谢

【问题讨论】:

    标签: xquery basex


    【解决方案1】:

    由于 XQuery 的语义,如果所有子节点都被新的父节点包裹,则需要复制它们。以下查询证明了这一点,该查询比较了原始节点和复制节点的节点身份。它将产生false:

    let $node := <node/>
    let $parent := <parent>{ $node }</parent>
    return $parent/node is $node
    

    由于复制数百万个节点的成本很高,这不可避免地会导致内存不足错误。

    如果您将结果写入文件,以下是解决此限制的实用解决方案:

    (:~ 
     : Writes element to a file, wrapped by a root node.
     : @param  $path      path to file
     : @param  $elements  elements to write
     : @param  $name      name of root node
     :)
    declare function local:write-to(
      $path      as xs:string,
      $elements  as element()*,
      $name      as xs:string
    ) as empty-sequence() {
      file:write-text($path, '<' || $name || '>'),
      file:append($path, $elements),
      file:append-text($path, '</' || $name || '>')
    };
    
    local:write-to('result.xml', <result/>, 'root')
    

    预测批评:这是一个明显的 hack。例如,该方法与BaseX的各种非默认序列化参数冲突(如果需要输出XML声明,则结果格式不正确等)。

    【讨论】:

    • 从来没有想过在这种情况下节点会被复制......这就解释了。我会尝试你的建议,然后带着 cmets 回来。非常感谢!
    【解决方案2】:

    使用 BaseX 9.0,您可以通过 COPYNODE 选项暂时禁用节点复制:

    (# db:copynode false #) {
      <xml>{
        for $item in collection('coll')//item
        return $item
      }</xml>
    }
    

    【讨论】:

    • 在这种情况下“暂时”意味着什么?
    • 暂时应该是指»在编译指示的范围内«。
    • 如果这和原来的效果一样,就是返回被包裹的节点,不知道为什么这不是默认行为,因为它不消耗资源......
    • pragma 绕过了 XQuery 规范的语义,因此作为可选特性引入。一个例子:let $x := &lt;x/&gt; return (# db:copynode false #) { &lt;_&gt;{ $x }&lt;/_&gt;/x is $x } 产生 true;没有编译指示,它会产生错误。
    猜你喜欢
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多