在Existdb中使用索引

时间:2018-11-30 12:42:00

标签: indexing xquery

回到我关于Exist-db中索引使用情况的问题.....我想优化以下查询的响应时间:

for $cana in doc("Events_sample.xml")//canal
for $prog in doc("Programs_sample.xml")//program [number(temporada)>1960 ][tipo_programa="Series"] [$cana//id_programa = number(@id_programa)] 
        order by $prog/titulo        
        return <tr class="modo2">
            <td>{$cana/string(@id_canal)}</td> 
            <td>{$prog/titulo}</td> 
            <td>{$prog/titulo_episodio}</td>
            <td>{$prog/generos}</td>
            <td>{$prog/id_serie}</td>
            <td>{$prog/episodio}</td>
            <td>{$prog/temporada}</td>
        </tr>

基本上,我有2个xml文件,一个保存有关在多个通道(> 100)中安排的所有程序的信息,第二个包含这些程序的详细信息。我想列出所有类型为“系列”的程序,其中季节编号为生产年份。这是第一个文件中列出的所有频道。

在我的PC上,此查询的评估需要2分钟以上的时间。我测试了具有类似结果的不同查询替代方案,以下是其中之一,它以略有不同的方式显示数据,并且没有性能改善:

    for $prog in doc("programs_sample.xml")//program [number(temporada)>1960 ][tipo_programa="Series"]
  return
     <tr class="modo2">
                <td>{doc("Events_sample.xml")//canal[$prog/number(@id_programa)=evento/id_programa]/string(@id_canal)}</td> 
                <td>{$prog/titulo}</td> 
                <td>{$prog/titulo_episodio}</td>
                <td>{$prog/generos}</td>
                <td>{$prog/id_serie}</td>
                <td>{$prog/episodio}</td>
                <td>{$prog/temporada}</td>
            </tr>

由于我不是xquery的专家,所以也许我仍然缺少一些额外的优化方法。...

XML文件的示例如下:

Programs.xml

    <?xml version="1.0" encoding="UTF-8"?>
<program_file fechaCreacion="20180919184224">
    <version>1.0</version>
    <programs>
        <program id_programa="1">
          <tipo_programa>Master</tipo_programa>
          <titulo >tit1</titulo>
          <año>2018</año>
        </program>
        <program id_programa="2">
          <tipo_programa>Master</tipo_programa>
          <titulo >tit1</titulo>
          <año>2018</año>
        </program>
           <program id_programa="3">
          <tipo_programa>Master</tipo_programa>
          <titulo >tit2</titulo>
          <año>2018</año>
        </program>
        <program id_programa="5">
          <id_serie>1</id_serie>
          <tipo_programa>Series</tipo_programa>
          <episodio>8</episodio>
          <titulo_episodio>Episod xx</titulo_episodio>
          <temporada>2016</temporada>
          <generos>serie comedia</generos>
          <titulo >tit1</titulo>
          <año>2018</año>
        </program>
        <program id_programa="6">
          <id_serie>2</id_serie>
          <tipo_programa>Series</tipo_programa>
          <episodio>8</episodio>
          <titulo_episodio>Episod yy</titulo_episodio>
          <temporada>2017</temporada>
          <titulo >tit1</titulo>
          <generos>serie comedia</generos>
          <año>2018</año>
        </program>
        <program id_programa="7">
          <id_serie>3</id_serie>
          <tipo_programa>Series</tipo_programa>
          <episodio>8</episodio>
          <temporada>2004</temporada>
          <titulo >tit2</titulo>
          <titulo_episodio>Episod zz</titulo_episodio>
          <generos>serie comedia</generos>
          <año>2018</año>
        </program>      
    </programs>
</program_file>

Events.xml

    <?xml version="1.0" encoding="UTF-8"?>
<schedule_file fechaCreacion="20181209202625">
  <version>1.0</version>
  <tipo_fichero>01</tipo_fichero>
  <subtipo_fichero>00</subtipo_fichero>
  <id_proveedor>001</id_proveedor>
  <nombre_proveedor>Orange</nombre_proveedor>
  <canales>
    <canal id_canal="TDPT" inicio_canal="20181207223000" fin_canal="20181224034500" duracion_canal="1401300">
      <evento>
        <id_evento>38008297</id_evento>
        <id_programa>1</id_programa>
        <fecha_inicio>20181207</fecha_inicio>
        <hora_inicio>223000</hora_inicio>
        <duracion>3600</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>S</HD>
        <CC>N</CC>
        <nuevo>N</nuevo>
        <tipo_audio lang="SPA" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
      <evento>
        <id_evento>38008307</id_evento>
        <id_programa>655979</id_programa>
        <fecha_inicio>20181207</fecha_inicio>
        <hora_inicio>233000</hora_inicio>
        <duracion>5400</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>S</HD>
        <CC>N</CC>
        <nuevo>N</nuevo>
        <tipo_audio lang="SPA" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
      <evento>
        <id_evento>38008308</id_evento>
        <id_programa>2</id_programa>
        <fecha_inicio>20181208</fecha_inicio>
        <hora_inicio>010000</hora_inicio>
        <duracion>5400</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>S</HD>
        <CC>N</CC>
        <nuevo>N</nuevo>
        <tipo_audio lang="SPA" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
      <evento>
        <id_evento>38008309</id_evento>
        <id_programa>529846</id_programa>
        <fecha_inicio>20181208</fecha_inicio>
        <hora_inicio>023000</hora_inicio>
        <duracion>600</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>S</HD>
        <CC>N</CC>
        <nuevo>N</nuevo>
        <tipo_audio lang="SPA" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
    </canal>
    <canal id_canal="MYZN" inicio_canal="20181207223000" fin_canal="20181224020000" duracion_canal="1395000">
      <evento>
        <id_evento>37864028</id_evento>
        <id_programa>3</id_programa>
        <fecha_inicio>20181207</fecha_inicio>
        <hora_inicio>223000</hora_inicio>
        <duracion>1800</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>N</HD>
        <CC>N</CC>
        <nuevo>N</nuevo>
        <tipo_audio lang="SPA" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
      <evento>
        <id_evento>37864029</id_evento>
        <id_programa>5</id_programa>
        <fecha_inicio>20181207</fecha_inicio>
        <hora_inicio>230000</hora_inicio>
        <duracion>3600</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>N</HD>
        <CC>N</CC>
        <nuevo>N</nuevo>
        <tipo_audio lang="spa" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
      <evento>
        <id_evento>37864607</id_evento>
        <id_programa>398729</id_programa>
        <fecha_inicio>20181208</fecha_inicio>
        <hora_inicio>000000</hora_inicio>
        <duracion>7200</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>N</HD>
        <CC>N</CC>
        <nuevo>N</nuevo>
        <tipo_audio lang="spa" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
      <evento>
        <id_evento>37872206</id_evento>
        <id_programa>413706</id_programa>
        <fecha_inicio>20181223</fecha_inicio>
        <hora_inicio>214000</hora_inicio>
        <duracion>4800</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>N</HD>
        <CC>N</CC>
        <nuevo>N</nuevo>
        <tipo_audio lang="spa" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
      <evento>
        <id_evento>37872207</id_evento>
        <id_programa>6</id_programa>
        <fecha_inicio>20181223</fecha_inicio>
        <hora_inicio>230000</hora_inicio>
        <duracion>3600</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>N</HD>
        <CC>N</CC>
        <nuevo>N</nuevo>
        <tipo_audio lang="spa" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
      <evento>
        <id_evento>37872259</id_evento>
        <id_programa>398729</id_programa>
        <fecha_inicio>20181224</fecha_inicio>
        <hora_inicio>000000</hora_inicio>
        <duracion>7200</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>N</HD>
        <CC>N</CC>
        <nuevo>N</nuevo>
        <tipo_audio lang="spa" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
    </canal>
    <canal id_canal="STCH" inicio_canal="20181207200100" fin_canal="20181224020100" duracion_canal="1404000">
      <evento>
        <id_evento>37601630</id_evento>
        <id_programa>641658</id_programa>
        <fecha_inicio>20181207</fecha_inicio>
        <hora_inicio>200100</hora_inicio>
        <duracion>10800</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>S</HD>
        <CC>N</CC>
        <nuevo>S</nuevo>
        <tipo_audio lang="SPA" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
      <evento>
        <id_evento>37601631</id_evento>
        <id_programa>7</id_programa>
        <fecha_inicio>20181207</fecha_inicio>
        <hora_inicio>230100</hora_inicio>
        <duracion>9720</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>S</HD>
        <CC>N</CC>
        <nuevo>N</nuevo>
        <tipo_audio lang="SPA" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
      <evento>
        <id_evento>37601632</id_evento>
        <id_programa>330720</id_programa>
        <fecha_inicio>20181208</fecha_inicio>
        <hora_inicio>014300</hora_inicio>
        <duracion>5820</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>S</HD>
        <CC>N</CC>
        <nuevo>N</nuevo>
        <tipo_audio lang="SPA" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
      <evento>
        <id_evento>37601633</id_evento>
        <id_programa>3</id_programa>
        <fecha_inicio>20181208</fecha_inicio>
        <hora_inicio>032000</hora_inicio>
        <duracion>5640</duracion>
        <vivo>N</vivo>
        <rating>TP</rating>
        <HD>S</HD>
        <CC>N</CC>
        <nuevo>S</nuevo>
        <tipo_audio lang="SPA" audio_description="0">Stereo</tipo_audio>
        <_3D>N</_3D>
        <voVos>0</voVos>
      </evento>
    </canal>
  </canales>
</schedule_file>

我正在使用的collection.xconf文件(保存到db / system / config / db / apps / MyApp)是:

<collection xmlns="http://exist-db.org/collection-config/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<index>
  <fulltext default="none" attributes="false"/>
    <lucene>
        <analyzer class="org.apache.lucene.analysis.standard.StandardAnalyzer">
            <param name="stopwords" type="org.apache.lucene.analysis.util.CharArraySet"/>
        </analyzer>    
        <text qname="tipo_programa"/>
        <text qname="temporada"/>
    </lucene>
    <range>

        <create qname="id_programa" type="xs:string"/>
        <create qname="temporada" type="xs:integer"/>
        <create qname="tipo_programa" type="xs:string"/>
        <create qname="program" type="xs:string"/>
    </range>
</index>

不幸的是,这不起作用,查询的速度和以前一样慢。我还检查了索引是使用MONEX创建的,但没有正确使用它们,只是Series索引的基本用法(附有屏幕截图)。

enter image description here enter image description here

我不知道我在做什么错.....任何提示都会受到欢迎。

2 个答案:

答案 0 :(得分:0)

没有适当的MWE,我只能为您提供一些一般性意见:

您的查询效率最高,无需使用过于复杂的library(rvest) pkgs <- read_html("https://cran.r-project.org/web/packages/available_packages_by_name.html") mylines <- pkgs %>% html_nodes("tr") %>% xml_text() nb_pkgs <- length(which(sapply(mylines, nchar)>5)) print(paste("There are", nb_pkgs, "packages available in CRAN as of", Sys.Date())) 语句。 第二个for循环同样是多余的。即使没有索引,将两者都删除将极大地提高性能。

清理完查询和示例后,我们可以再来看一下在exist-db中配置索引。

您可以在documentation

中找到有关如何编写有效查询的更多信息。

答案 1 :(得分:0)

由于您的第一个查询格式不正确,所以我无法适应它,但可以运行第二个查询。未经任何修改,此查询将在不到一秒钟的时间内对样本数据运行。我们可以看到有三个对范围索引的调用,一个成功两次失败。initial run

原因有两个:

  1. 您的索引配置使用错误的类型,您在查询中使用number()进行了转换。这意味着您首先创建一个字符串索引,然后强制执行无法使用该索引的转换,而不是首先简单地将字段索引为数字并节省往返次数。
  2. 您缺少在[]中查询的某些属性。为了充分利用索引,应该对查询中使用的所有表达式进行索引。

给出以下conf.xml

    <collection xmlns="http://exist-db.org/collection-config/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <index>
      <fulltext default="none" attributes="false"/>
     <!-- Lucene was superflous for your use case    -->
        <range>
     <!--  this was missing some values used in your query  -->
            <create qname="id_programa" type="xs:integer"/>
            <create qname="temporada" type="xs:integer"/>
             <create qname="tipo_programa" type="xs:string"/>
            <create qname="program" type="xs:string"/>
            <create qname="@id_canal" type="xs:string"/>
            <create qname="@id_programa" type="xs:integer"/>
        </range>
     </index>
     </collection>

和此修改后的查询:

xquery version "3.1";

(: Follow the standard layout of exist's expath packages :)
 import module namespace config="http://so-53557816/config" at "config.xqm";

 declare variable $events := doc($config:data-root || '/Events.xml');
 declare variable $programs := doc($config:data-root || '/Programs.xml');

(: temporada is a number no need to convert :)
(: go to al programms after 1960 that are a series :)
 for $prog in $programs//program[temporada >1960 ][tipo_programa="Series"]

(: complex xpath expressions should be evaluated once inside a let statement for greater legibiliy :)
(: look up channel id for each $prog :)
 let $cana := $events//id_programa[. = $prog/@id_programa]/../../@id_canal

  return
     <tr class="modo2">
                <td>{$cana}</td> 
                <td>{$prog/titulo}</td> 
                <td>{$prog/titulo_episodio}</td>
                <td>{$prog/generos}</td>
                <td>{$prog/id_serie}</td>
                <td>{$prog/episodio}</td>
                <td>{$prog/temporada}</td>
            </tr>

所有三个查询都会使用范围索引(此处无需使用lucene全文索引)full index usage

您可以下载代码为here.xar示例应用程序,在这里我还采用了更标准的应用程序布局。将数据文件包含在/data/集合中,并将查询代码存储在/modules/join.xql中。

查询返回:

<tr class="modo2">
    <td id_canal="MYZN"/>
     <td>
        <titulo>tit1</titulo>
    </td>
    <td>
        <titulo_episodio>Episod xx</titulo_episodio>
    </td>
    <td>
        <generos>serie comedia</generos>
    </td>
    <td>
        <id_serie>1</id_serie>
    </td>
    <td>
        <episodio>8</episodio>
    </td>
    <td>
        <temporada>2016</temporada>
    </td>
 </tr>
 <tr class="modo2">
    <td id_canal="MYZN"/>
    <td>
        <titulo>tit1</titulo>
    </td>
    <td>
        <titulo_episodio>Episod yy</titulo_episodio>
    </td>
    <td>
        <generos>serie comedia</generos>
    </td>
    <td>
        <id_serie>2</id_serie>
    </td>
    <td>
        <episodio>8</episodio>
    </td>
    <td>
        <temporada>2017</temporada>
    </td>
 </tr>
 <tr class="modo2">
    <td id_canal="STCH"/>
    <td>
        <titulo>tit2</titulo>
    </td>
    <td>
        <titulo_episodio>Episod zz</titulo_episodio>
    </td>
    <td>
        <generos>serie comedia</generos>
    </td>
    <td>
        <id_serie>3</id_serie>
    </td>
    <td>
        <episodio>8</episodio>
    </td>
    <td>
        <temporada>2004</temporada>
    </td>
 </tr>