Использование индексов с Existdb - PullRequest
0 голосов
/ 30 ноября 2018

Возвращаясь к моему вопросу об использовании индексов в 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), причем вторая включает подробную информацию об этих программах.И я хочу перечислить все программы типа «Серии» с номером сезона, являющимся годом производства.И это для всех каналов, перечисленных в первом файле.

Оценка этого запроса занимает более 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, но их использование не используется должным образом, только базовое использование для индекса серии (скриншоты прилагаются).

enter image description here enter image description here

Я не знаю, что я делаю неправильно ..... любые подсказки будутприветствуется.

Ответы [ 2 ]

0 голосов
/ 23 декабря 2018

Так как ваш первый запрос не правильно сформирован, я не могу его адаптировать, но я могу выполнить ваш второй запрос.Без каких-либо изменений этот запрос выполняется менее чем за секунду для данных образца.Мы можем видеть, что есть три вызова индекса диапазона, один успешный два сбоя. 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>

приводит ко всем трем поискам, чтобы использовать диапазонindex (здесь нет необходимости в полнотекстовых индексах Lucene) full index usage

Вы можете загрузить .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>
0 голосов
/ 03 декабря 2018

Без надлежащего MWE Я могу предложить вам только некоторые общие замечания:

Ваш запрос максимально неэффективен, нет необходимости в слишком сложном операторе where.Второй цикл for одинаково лишний.Избавление от обоих значительно улучшит производительность, даже без индексов.

Как только вы очистите свой запрос и примеры, мы можем еще раз взглянуть на настройку индексов в exist-db.

Более подробную информацию о том, как писать эффективные запросы, можно найти в документации

.
...