Xquery 中联接的性能问题
Performance Issue of a Join in Xquery
我在多个级别执行连接时遇到一个奇怪的性能问题,假设我有一个巨大的 xml,我需要从中执行连接(在那个巨大的 xml 内的记录上,大约几千)并定义 4 个层级(Parent/Child 关系)。但是,在三个级别加入(每个级别一个加入)工作正常但在第 4 级别加入需要几个小时才能完成。非常感谢任何意见和指导。谢谢。
例如:来源XML
<items>
<item>
<level>1</level>
<parentref></parentref>
<parentitem></parentitem>
<itemno>123</itemno>
<itemname>Laptop</itemname>
</item>
<item>
<level>2</level>
<parentref>1</parentref>
<parentitem>123</parentitem>
<itemno>111</itemno>
<itemname>Keyboard</itemname>
</item>
<item>
<level>2</level>
<parentref>1</parentref>
<parentitem>123</parentitem>
<itemno>112</itemno>
<itemname>Mouse</itemname>
</item>
<item>
<level>3</level>
<parentref>2</parentref>
<parentitem>112</parentitem>
<itemno>112-1</itemno>
<itemname>Fiber Mouse</itemname>
</item>
<item>
<level>4</level>
<parentref>3</parentref>
<parentitem>112-1</parentitem>
<itemno>112-2</itemno>
<itemname>Mouse Pad and USB</itemname>
</item>
</items>
预期输出:
<items>
<item>
<itemno>123</itemno>
<itemname>Laptop</itemname> -- Level 1 ( Top level always be one record)
<accessories> -------------------------------
<itemno>111</itemno>
<itemname>Keyboard</itemname> -- Both accessories belong to Level 2 ( can be any number of records)
</accessories> one of the accessories has two levels ( can be any number of records)
<accessories>
<itemno>112</itemno>
<itemname>Mouse</itemname>
<addons>
<itemno>112-1</itemno>
<itemname>Fiber Mouse</itemname>
<moreaddons> --- Performance issue is at this level of join
<itemno>112-2</itemno> For 500 addons records, I have almost 5000 moreaddons to match in my source xml.
<itemname>Mouse Pad and USB</itemname>
</moreaddons>
</addons>
</accessories>
</item>
我在下面使用的示例加入代码:
1级:获得基础物品
for $x in input xml
where $x/level=1
第 2 级:获得给定基础物品的配件
for $y in $x
for $i in input xml
where $i/level=2
and $y/itemno = $i/parentitem
级别 3:获取给定配件的插件
let $p := (for $bv in $i return $bv)
let $lst := (for $id in input xml
where $ids/level=3 return $id)
return for-each($p,function($p){
if(for-each($lst,function($lst){$p/itemno=$lst/parentitem})=true()
then for $av in input xml
where $av/level = 3
and $av/parentitem=$p/itemno
第 4 级:获取给定插件的更多插件
let $q := (for $cv in $av return $cv)
let $lsts := (for $ids in input xml
where $ids/level=4 return $ids)
return for-each($q,function($q){
if(for-each($lsts,function($lsts){$q/itemno=$lsts/parentitem})=true()
then for $dv in input xml
where $dv/level = 4
and $dv/parentitem=$q/itemno
直接的嵌套 for..return
方法看起来像
<items>
{
for $level1-item in /items/item[level = 1]
return
<item>
{
$level1-item!(itemno, itemname),
for $level2-item in /items/item[level = 2 and parentitem = $level1-item/itemno]
return
<accessories>
{
$level2-item!(itemno, itemname),
for $level3-item in /items/item[level = 3 and parentitem = $level2-item/itemno]
return
<addons>
{
$level3-item!(itemno, itemname),
for $level4-item in /items/item[level = 4 and parentitem = $level3-item/itemno]
return
<moreaddons>
{
$level4-item!(itemno, itemname)
}
</moreaddons>
}
</addons>
}
</accessories>
}
</item>
}
</items>
最终嵌套要求一个函数采用一个级别:
declare variable $names as xs:string* external := ('item', 'acessories', 'addons', 'moreaddons');
declare function local:nest($root as document-node()) as element()*
{
let $level := 1
for $item in $root/items/item[level = $level]
return
element { $names[$level] } {
$item/itemno,
$item/itemname,
local:nest($root, $item, $level + 1)
}
};
declare function local:nest($root as document-node(), $parent as element(item), $level as xs:integer) as element()*
{
for $item in $root/items/item[level = $level and parentitem = $parent/itemno]
return
element { $names[$level] } {
$item/itemno,
$item/itemname,
local:nest($root, $item, $level + 1)
}
};
<items>
{
local:nest(/)
}
</items>
我在多个级别执行连接时遇到一个奇怪的性能问题,假设我有一个巨大的 xml,我需要从中执行连接(在那个巨大的 xml 内的记录上,大约几千)并定义 4 个层级(Parent/Child 关系)。但是,在三个级别加入(每个级别一个加入)工作正常但在第 4 级别加入需要几个小时才能完成。非常感谢任何意见和指导。谢谢。 例如:来源XML
<items>
<item>
<level>1</level>
<parentref></parentref>
<parentitem></parentitem>
<itemno>123</itemno>
<itemname>Laptop</itemname>
</item>
<item>
<level>2</level>
<parentref>1</parentref>
<parentitem>123</parentitem>
<itemno>111</itemno>
<itemname>Keyboard</itemname>
</item>
<item>
<level>2</level>
<parentref>1</parentref>
<parentitem>123</parentitem>
<itemno>112</itemno>
<itemname>Mouse</itemname>
</item>
<item>
<level>3</level>
<parentref>2</parentref>
<parentitem>112</parentitem>
<itemno>112-1</itemno>
<itemname>Fiber Mouse</itemname>
</item>
<item>
<level>4</level>
<parentref>3</parentref>
<parentitem>112-1</parentitem>
<itemno>112-2</itemno>
<itemname>Mouse Pad and USB</itemname>
</item>
</items>
预期输出:
<items>
<item>
<itemno>123</itemno>
<itemname>Laptop</itemname> -- Level 1 ( Top level always be one record)
<accessories> -------------------------------
<itemno>111</itemno>
<itemname>Keyboard</itemname> -- Both accessories belong to Level 2 ( can be any number of records)
</accessories> one of the accessories has two levels ( can be any number of records)
<accessories>
<itemno>112</itemno>
<itemname>Mouse</itemname>
<addons>
<itemno>112-1</itemno>
<itemname>Fiber Mouse</itemname>
<moreaddons> --- Performance issue is at this level of join
<itemno>112-2</itemno> For 500 addons records, I have almost 5000 moreaddons to match in my source xml.
<itemname>Mouse Pad and USB</itemname>
</moreaddons>
</addons>
</accessories>
</item>
我在下面使用的示例加入代码:
1级:获得基础物品
for $x in input xml
where $x/level=1
第 2 级:获得给定基础物品的配件
for $y in $x
for $i in input xml
where $i/level=2
and $y/itemno = $i/parentitem
级别 3:获取给定配件的插件
let $p := (for $bv in $i return $bv)
let $lst := (for $id in input xml
where $ids/level=3 return $id)
return for-each($p,function($p){
if(for-each($lst,function($lst){$p/itemno=$lst/parentitem})=true()
then for $av in input xml
where $av/level = 3
and $av/parentitem=$p/itemno
第 4 级:获取给定插件的更多插件
let $q := (for $cv in $av return $cv)
let $lsts := (for $ids in input xml
where $ids/level=4 return $ids)
return for-each($q,function($q){
if(for-each($lsts,function($lsts){$q/itemno=$lsts/parentitem})=true()
then for $dv in input xml
where $dv/level = 4
and $dv/parentitem=$q/itemno
直接的嵌套 for..return
方法看起来像
<items>
{
for $level1-item in /items/item[level = 1]
return
<item>
{
$level1-item!(itemno, itemname),
for $level2-item in /items/item[level = 2 and parentitem = $level1-item/itemno]
return
<accessories>
{
$level2-item!(itemno, itemname),
for $level3-item in /items/item[level = 3 and parentitem = $level2-item/itemno]
return
<addons>
{
$level3-item!(itemno, itemname),
for $level4-item in /items/item[level = 4 and parentitem = $level3-item/itemno]
return
<moreaddons>
{
$level4-item!(itemno, itemname)
}
</moreaddons>
}
</addons>
}
</accessories>
}
</item>
}
</items>
最终嵌套要求一个函数采用一个级别:
declare variable $names as xs:string* external := ('item', 'acessories', 'addons', 'moreaddons');
declare function local:nest($root as document-node()) as element()*
{
let $level := 1
for $item in $root/items/item[level = $level]
return
element { $names[$level] } {
$item/itemno,
$item/itemname,
local:nest($root, $item, $level + 1)
}
};
declare function local:nest($root as document-node(), $parent as element(item), $level as xs:integer) as element()*
{
for $item in $root/items/item[level = $level and parentitem = $parent/itemno]
return
element { $names[$level] } {
$item/itemno,
$item/itemname,
local:nest($root, $item, $level + 1)
}
};
<items>
{
local:nest(/)
}
</items>