Right now the query takes around 2 minutes , before I made some changes it took 3:48m.
The xml documents are taken from a web pages , due to it changes each 5m and gives information about the buses in real time.
Could you help me to optimize this query?
xquery version "3.0";
declare namespace bus="http://docs.gijon.es/sw/busgijon.asmx";
declare function local:getNombreParada($numero)
{
for $parada in doc("http://datos.gijon.es/doc/transporte/busgijoninfo.xml")//paradas/bus:parada
where $numero=$parada/bus:idparada
return $parada/bus:descripcion
};
declare function local:getBusesPorLinea($linea)
{
let $numero:=$linea
let $nBuses:=count(doc("http://datos.gijon.es/doc/transporte/busgijontr.xml")//bus:llegada[bus:idlinea=$numero])
return
if($nBuses=0)
then(<p>No hay ningun bus en esta linea</p>)
else(
<div>
<h2>Numero de buses funcionando en la linea {$numero} : {$nBuses}</h2>
<table class="table table-hover">
<thead>
<tr>
<th>Parada</th>
<th>Minutos hasta la llegada</th>
</tr>
</thead>
<tbody>
{
for $l in doc("http://datos.gijon.es/doc/transporte/busgijontr.xml")//bus:llegada[bus:idlinea=$numero]
for $parada in doc("http://datos.gijon.es/doc/transporte/busgijoninfo.xml")//paradas/bus:parada[bus:idparada=$l/bus:idparada]
return <tr>
<td>{$parada/bus:descripcion}</td>
<td>{$l/bus:minutos}</td></tr>
}
</tbody>
</table>
</div>
)
};
local:getBusesPorLinea(1)
PD:i am running this in exist Db
Are documents cached? I'm not an expert, but your code seems to access the same document multiple times. That's OK if you're sure the content is cached in the executing environment. Otherwise I would try to declare
declare variable $docinfo := doc("http://datos.gijon.es/doc/transporte/busgijoninfo.xml");
declare variable $doctr := doc("http://datos.gijon.es/doc/transporte/busgijontr.xml");
to make sure the files are fetched just once.
You also scan documents at least twice for same kind of data. I would do that once:
declare variable $paradas := $docinfo//paradas;
declare variable $llegadas := $doctr//bus:llegada;
then only filter the collections:
declare function local:getNombreParada($numero)
{
$paradas/bus:parada[bus:idparada = $numero]/bus:descripcion
};
declare function local:getBusesPorLinea($linea)
{
let $numero:=$linea
let $llegadasNum:=$llegadas[bus:idlinea=$numero]
let $nBuses:=count($llegadasNum)
return
if($nBuses=0)
then(<p>No hay ningun bus en esta linea</p>)
else(
<div>
<h2>Numero de buses funcionando en la linea {$numero} : {$nBuses}</h2>
<table class="table table-hover">
<thead>
<tr>
<th>Parada</th>
<th>Minutos hasta la llegada</th>
</tr>
</thead>
<tbody>
{
for $l in $llegadasNum
for $parada in $paradas/bus:parada[bus:idparada=$l/bus:idparada]
return <tr>
<td>{$parada/bus:descripcion}</td>
<td>{$l/bus:minutos}</td></tr>
}
</tbody>
</table>
</div>
)
};
May be that is not much faster, but I hope it is a bit more readable.