如何在 FLWOR(并行化)中优化 XQuery fn:count()?
How to optimize XQuery fn:count() in FLWOR (Parallelize)?
我正在使用 BaseX XML 数据库并且有很多 XML 数据,大约 50 000 个不同大小的文件。
但是,我实现的一个本地功能是计算量大。不幸的是,它在我的工作中非常重要。
让我们假设每个学生有 50 000 个文件,并且每个学生都有一个名为 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 分钟。想象一下 50 000 名学生。它要么崩溃要么超时,我无法调试它。让它计算了一夜,然后回来,什么也没发生。
有没有办法优化这个?由于使用 @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
,不确定这是否是问题中的拼写错误或者可能是索引不起作用的原因。
我正在使用 BaseX XML 数据库并且有很多 XML 数据,大约 50 000 个不同大小的文件。 但是,我实现的一个本地功能是计算量大。不幸的是,它在我的工作中非常重要。
让我们假设每个学生有 50 000 个文件,并且每个学生都有一个名为 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 分钟。想象一下 50 000 名学生。它要么崩溃要么超时,我无法调试它。让它计算了一夜,然后回来,什么也没发生。
有没有办法优化这个?由于使用 @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
,不确定这是否是问题中的拼写错误或者可能是索引不起作用的原因。