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

dd321

我正在使用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,不确定是否是问题中的错字,或者是索引不起作用的原因。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章