繁体   English   中英

如何在FLWOR(Parallelize)中优化XQuery fn:count()?

[英]How to optimize XQuery fn:count() in FLWOR (Parallelize)?

我正在使用BaseX XML数据库,并且有很多XML数据,大约有5万个各种大小的文件。 但是,我实现的本地功能之一是计算量大。 不幸的是,这对我的工作至关重要。

让我们假设我每个学生都有5万个文件,每个学生都有一个名为friend的属性。 我想为每个学生找出该学生有多少个朋友。

以下是一些示例代码:

declare variable $context := /Students

declare function local:CalculateFriends($student)
{
 let $studentName := $student/@Name
 return fn:count($context[@friend = $studentName])
}

for $s in $context
let $numberOfFriends := local:CalculateFriends($s)
return <Student Name = '{$s/@Name}' NumberOfFriends = '{$numberOfFriends}' />

此代码工作正常进行单一的学生。 对于1000名学生,大约需要5分钟。 想象一下有5万名学生。 它崩溃或超时,我无法调试它。 留下来计算一夜,然后回来,什么也没发生。

有没有一种方法可以对此进行优化? 由于使用@friend = $studentName因此它利用了属性索引(已启用)。 在大学上了并行课程后,我的第一个想法是将count和flwor语句并行化为块,类似于OpenMP。 但是经过一些研究,它似乎不支持并行查询。

有人对如何解决此问题有任何想法吗?

谢谢!

编辑:XML结构的示例

<Student Name="Kevin" friend="Alvin" BirthDate="1985-06-29" etc..>
  <More meta data> ....... />
</Student>

似乎可以将这个问题视为一个分组问题,其中必须计算组的成员,以便您可以尝试是否

let 
  $friendsMap as map(xs:string, xs:integer) := 
    map:merge(
        for $student in $context
        group by $friend := $student/@Friend/string()
        return map { $friend : count($student) }
    )
for $s in $context return <Student Name = '{$s/@Name}' NumberOfFriends = '{$friendsMap($s/@Name)}' />

鉴于分组通常通过使用键来提高效率来支持,因此其性能更好。

不知道它是否对解决BaseX和特定问题有帮助,而是发布答案而不是注释来以某种可读的方式建议代码。

在您发布的代码片段中,唯一的另一个问题似乎是该示例具有一个拼写为Friend的属性,而XPath搜索@friend ,不确定这是该问题的错字还是索引无效的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM