2013-02-10 26 views
1

我使用stylus studio(使用DATA DIRECT)/ xQuery將兩個xml文件合併爲一個文件(文件先從CSV轉換爲xml,然後加入)。 客戶(標題)數據首先被讀取,然後匹配每個客戶讀取的交易數據。 (使用循環) 交易數據也按交易日期(年)分組。 Thisi是通過使用不同的功能完成的。 交易數據文件非常大,處理起來很慢。我正在尋找提高性能的方法。 任何幫助。建議很受歡迎。下面是 是使用的代碼。 謝謝。XQuery性能

(:options:) 
declare option ddtek:xml-streaming "yes"; 
declare option ddtek:serialize "encoding=UTF-8, 
       omit-xml-declaration=no, indent=yes"; 

(:external variables:) 
declare variable $esa-h-converter as xs:string external; 
declare variable $esa-t-converter as xs:string external; 
declare variable $input-h-data-path as xs:string external; 
declare variable $input-t-data-path as xs:string external; 


(:main:) 
<ROOT_NODE> 
    { 
    let $heads := doc(fn:concat(
         "converter:", 
         $esa-h-converter, 
         "?file:///", 
         $input-h-data-path)) 
        /DATA_ROOT/CUSTOMER 

    for $record at $primaryKey in $heads 

    return 
     <TEMPLATE> 
     <CUSTOMER> 
      <RECORD_COUNT>{ $primaryKey }</RECORD_COUNT> 
      <HD_REGION>{ $record/HD_REGION/text() }</HD_REGION> 
      <HD_CONT>{ $record/HD_CONT/text() }</HD_CONT> 
      <HD_FRDATE>{ $record/HD_FRDATE/text() }</HD_FRDATE> 
      <HD_TODATE>{ $record/HD_TODATE/text() }</HD_TODATE> 
      <HD_CUSNAME>{ $record/HD_CUSNAME/text() }</HD_CUSNAME> 
      <HD_ADDR1>{ $record/HD_ADDR1/text() }</HD_ADDR1> 
      <HD_ADDR2>{ $record/HD_ADDR2/text() }</HD_ADDR2> 
      <HD_ADDR3>{ $record/HD_ADDR3/text() }</HD_ADDR3> 
      <HD_ADDR4>{ $record/HD_ADDR4/text() }</HD_ADDR4> 
      <HD_STATE>{ $record/HD_STATE/text() }</HD_STATE> 
      <HD_SUBTOWN>{ $record/HD_SUBTOWN/text() }</HD_SUBTOWN> 
      <HD_PCODE>{ $record/HD_PCODE/text() }</HD_PCODE> 
      { 

      let $my-transactions := 
       doc(fn:concat("converter:", 
           $esa-t-converter, 
           "?file:///", 
           $input-t-data-path)) 
           /DATA_ROOT 
           /TRANSACTION 
          [TR_CONT eq $record/HD_CONT 
           and TR_REGION eq $record/HD_REGION] 
      let $years := fn:distinct-values(
          $my-transactions 
          /fn:substring(TR_DATE/text(), 1, 4)) 
      for $period in $years 
      return 
       <PERIOD> 
       <RECORD_COUNT>{ $primaryKey }</RECORD_COUNT> 
       <YEAR>{ $period }</YEAR> 
       { 
        $my-transactions 
        [fn:substring(TR_DATE/text(), 1, 4) = $period] 
       }    
       </PERIOD> 
      } 
     </CUSTOMER> 
     </TEMPLATE> 
    } 
</ROOT_NODE> 

回答

1

性能通常取決於具體產品和具體數據很多,所以採取一切你半信半疑來到這裏的建議,並相信它之前測試它自己。我希望有人比我更熟悉Data Direct的處理器將能夠衡量您的問題。不過話說回來,發生了我幾件事情是值得一試:

  • 你可以嘗試先排序按客戶的交易文件,然後進行合併。如果交易文件很長,那麼排序不會很快。

  • 而不是訪問主文件中的每個記錄並查找它的交易,您可能(給定客戶組織的交易文件)訪問交易文件中的每個客戶並執行合併。

  • 您的內部FLWOR表達式在整個事務文件中執行兩個選擇,涉及查看fn:substring(TR_DATE/text(), 1, 4) - 這似乎很可能會擊敗幾乎所有XQuery引擎的優化器。如果引擎在日期上構建了索引,則查看子字符串可確保查詢處理器無法對該值執行簡單的索引查找,但必須掃描索引中的所有值(或可能掃描文檔中的所有值)進行比賽。

    既然你說你正在爲這兩個文件創建XML,我想你可以提取那年的子字符串,並把它(冗餘)放在一個單獨的元素或屬性中。這將使原則上XQuery引擎可以構建索引並使用索引查找而不是掃描來執行選擇的那部分。 (不管你的特定處理器是否有幫助,我不知道。)

+0

感謝您的回覆。我會考慮在數據轉換過程中剝離一年。瀏覽交易文件不在選項中,因爲可能有多個匹配的頭部記錄用於一組交易。謝謝。 – 2013-02-12 11:39:15