<docbook><section><title>VirtSPARQLOptGuideEx1</title><title>Optimizing query performance using bif functions Example</title>Optimizing query performance using bif functions Example
<para>The following example describes how to optimize query performance using bif functions.</para>
<orderedlist spacing="compact"><listitem>Suppose there is the following query, which performs very well on Virtuoso db with default indexes:: <programlisting>SELECT DISTINCT
    ?r
    (bif:concat(bif:search_excerpt(bif:vector(&#39;lego&#39;), ?v2))) as ?_n_f_t_m_ex_
WHERE 
  {
    { ?r ?v1 ?v2 .
      ?v2 bif:contains &#39;lego&#39; .
    }
    UNION
    { ?r ?v1 ?v3 .
      ?v3 ?v4 ?v2 .
      ?v4 rdfs:subPropertyOf rdfs:label .
      ?v2 bif:contains &#39;lego&#39; .
    } .
  } 
LIMIT 10
</programlisting></listitem>
<listitem>Suppose also there should be hidden certain types from the user.
 For the purposes of this, to the end of the query is added <emphasis>nao:userVisible</emphasis> property: <programlisting>SELECT DISTINCT
    ?r
    (bif:concat(bif:search_excerpt(bif:vector(&#39;lego&#39;), ?v2))) as ?_n_f_t_m_ex_
WHERE 
  {
    { ?r ?v1 ?v2 .
      ?v2 bif:contains &#39;lego&#39; .
    }
    UNION
    { ?r ?v1 ?v3 .
      ?v3 ?v4 ?v2 .
      ?v4 rdfs:subPropertyOf rdfs:label .
      ?v2 bif:contains &#39;lego&#39; .
    } .
    ?r nao:userVisible &quot;1&quot;^^xsd:int .
  } 
LIMIT 10
</programlisting></listitem>
<listitem><emphasis>The optimization:</emphasis> <orderedlist spacing="compact"><listitem>Replacing <emphasis> &quot;?r nao:userVisible 1&quot;</emphasis> with a <emphasis>bif:exists</emphasis> filter makes the query performance significant fast.
</listitem>
<listitem>Add <emphasis>Limit</emphasis> to each UNION, because in this case no one side of union will needlessly generate data that does not fit LIMIT 10.
</listitem>
<listitem>Some triples should reside in one graph, if this is applicable to the task in question.
 E.g.
 if both <emphasis>?r ?v1 ?v2 .</emphasis> and <emphasis>?r nao:userVisible &quot;1&quot;^^xsd:int .</emphasis> are supposed to be in same graph, then: <programlisting>?r ?v1 ?v2 .
?v2 bif:contains &#39;lego&#39; .
-- can be replaced with:
graph ?g 
  { 
    ?r ?v1 ?v2 .
    ?r nao:userVisible &quot;1&quot;^^xsd:int .
    ?v2 bif:contains &#39;lego&#39; . 
  }
</programlisting></listitem>
</orderedlist></listitem>
<listitem>Finally, here is the optimized query: <programlisting>PREFIX nao: &lt;http://www.semanticdesktop.org/ontologies/2007/08/15/nao#&gt;
SELECT DISTINCT
    ?r
    (bif:concat(bif:search_excerpt(bif:vector(&#39;lego&#39;), ?v2))) as
        ?_n_f_t_m_ex_
WHERE 
  {
    {
      {
        SELECT DISTINCT ?r ?v2 
        WHERE
          { 
            ?r ?v1 ?v2 .
            ?v2 bif:contains &#39;lego&#39; .
            ?r nao:userVisible &quot;1&quot;^^xsd:int .
          } 
        LIMIT 10 
      } 
    }
    UNION
    {
      {
        SELECT DISTINCT ?r ?v2 
        WHERE
          { 
            ?r ?v1 ?v3 .
            ?v3 ?v4 ?v2 .
            ?v4 rdfs:subPropertyOf rdfs:label .
            ?v2 bif:contains &#39;lego&#39; .
            ?r nao:userVisible &quot;1&quot;^^xsd:int .
          } 
        LIMIT 10 
      } 
    }
  } 
LIMIT 10
</programlisting> </listitem>
</orderedlist><bridgehead class="http://www.w3.org/1999/xhtml:h2">Related</bridgehead>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="VirtSPARQLOptGuide">Virtuoso SPARQL Optimization Guide</ulink> </listitem>
</itemizedlist></section></docbook>