XQuery最大分段错误

时间:2017-04-24 14:23:59

标签: xml xpath xquery xqilla

我试图使用带有the XML version of the mondial database的XQuery / XPath来找到彼此距离最远的两个城市,只考虑人口高于500,000的城市。为了计算距离,我假设Mercator projection

这是我的代码:

let $db := doc("mondial.xml")

(: Cities with 500,000+ population :)
let $cities := (for $city in $db/mondial/country//city
(: Compare using latest population data :)
where $city/population[@year = max($city/population/@year)] > 500000
return $city)

(: City pairs and the distances between them (not
not square-rooted as all we care about is order) :)
let $distancesSquared := (for $city1 in $cities
for $city2 in $cities
    where $city1 != $city2
    return <distancesquared city1="{ data($city1/name) }" city2="{ data($city2/name) }">{ (
        let $diffLong := number($city1/longitude) - number($city2/longitude)
        let $diffLat := number($city1/latitude) - number($city2/latitude)
        return $diffLong * $diffLong + $diffLat * $diffLat
    ) }</distancesquared>)

let $max := max($distancesSquared)

return $distancesSquared[data(.) = $max]

但出于某种原因,我在这一行得到了一个分段错误:

let $max := max($distancesSquared)

我使用xqilla运行查询,如下所示:

xqilla -o query.xml query.xq

任何想法我的代码可能出错?

1 个答案:

答案 0 :(得分:3)

这是一个非常糟糕的查询,因为中间数据量与输入数据量呈二次方变化。

因为变量$ distanceSquared被引用了两次,所以它几乎肯定会在内存中实现,而且可能很大。

首先检查是否仍有少量数据发生故障。如果即使使用小数据集也会发生这种情况,那么您的代码没有任何问题,它是XQuilla中的一个错误。

如果仅在大型数据集中发生,那么您可能超出某种系统限制(可能是内存);检查是否有可以调整的配置参数。

更好:找到改进的算法。

作为第一步,尝试一种时间仍然是二次方的算法,但不再是二次方的记忆:具体来说,对于每个城市,找到距离最远的城市;以

的形式构建一个列表
<city name="London" furthest="Christchurch" distance="8000"/>

等;然后在这个城市对列表中找到最大值。

更聪明的是,有一些方法可以在不检查所有城市对的情况下解决这个问题。我害怕它已经有一段时间了,因为我研究了这样的算法,所以我不记得细节。但一般的想法是将每个城市分配到一个区域,计算出每对区域中各点之间的极端距离,然后在找到某个城市中最远的城市时,只处理距离足够远的区域。