1

我使用 stylus studio(带有 DATA DIRECT)/xQuery 将两个 xmls 文件合并为一个(文件先从 CSV 转换为 xml,然后再加入)。首先读取客户(标题)数据,然后为每个客户读取匹配交易数据。(使用循环)交易数据也按交易日期(年份)分组。这是通过使用 distinct 函数完成的。交易数据文件很大,处理速度很慢。我正在寻找提高性能的方法。任何帮助。建议很受欢迎。下面是使用的代码。谢谢。

(: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> 
4

1 回答 1

1

性能通常在很大程度上取决于单个产品和特定数据,因此请对您在这里获得的所有建议持保留态度,并在相信之前自己进行测试。我希望比我更熟悉 Data Direct 处理器的人能够回答您的问题。但是话虽如此,但我想到了几件事可能值得尝试:

  • 您可以先尝试按客户对交易文件进行排序,然后再执行合并。如果事务文件很长,排序不会很快。

  • 您可以(给定由客户组织的交易文件)访问交易文件中的每个客户并执行合并,而不是访问主文件中的每条记录并为其查找交易。

  • 您的内部 FLWOR 表达式正在整个事务文件中进行两个选择,其中涉及查看fn:substring(TR_DATE/text(), 1, 4)——这似乎很可能会破坏几乎所有 XQuery 引擎的优化器。如果引擎在日期上建立了索引,那么查看子字符串可确保查询处理器无法对值进行简单的索引查找,但必须扫描索引中的所有值(或者可能是文档中的所有值) 匹配。

    既然您说您正在为这两个文件创建 XML,我想您可以提取该年份子字符串并将其(冗余地)放在单独的元素或属性中。原则上,这将使 XQuery 引擎能够构建索引并使用索引查找而不是扫描来执行该部分选择。(我不知道这对您的特定处理器是否有帮助。)

于 2013-02-10T20:02:34.683 回答