簡體   English   中英

Xquery 中連接的性能問題

[英]Performance Issue of a Join in Xquery

在多個級別執行連接時,我有一個奇怪的性能問題,比如我有一個巨大的 xml,我需要從中執行連接(在那個巨大的 xml 中的記錄上,大約幾千個)並定義 4 個層次結構級別(父/子關系)。 但是,三個級別的聯接(每個級別一個聯接)工作正常,但第 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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM