回到我关于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索引的基本用法(附有屏幕截图)。
我不知道我在做什么错.....任何提示都会受到欢迎。
答案 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)
由于您的第一个查询格式不正确,所以我无法适应它,但可以运行第二个查询。未经任何修改,此查询将在不到一秒钟的时间内对样本数据运行。我们可以看到有三个对范围索引的调用,一个成功两次失败。
原因有两个:
number()
进行了转换。这意味着您首先创建一个字符串索引,然后强制执行无法使用该索引的转换,而不是首先简单地将字段索引为数字并节省往返次数。 []
中查询的某些属性。为了充分利用索引,应该对查询中使用的所有表达式进行索引。 给出以下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全文索引)
您可以下载代码为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>