cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject [CONF] Apache Cayenne Documentation > Prefetching
Date Mon, 07 Sep 2009 23:40:00 GMT
    <base href="">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=CAYDOC&amp;forWysiwyg=true"
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="">Prefetching</a></h2>
     <h4>Page <b>edited</b> by             <a href="">Andrus
     <div class="notificationGreySide">
         <h3><a name="Prefetching-IntroductiontoPrefetching"></a>Introduction
to Prefetching</h3>

<p>Prefetching is a performance optimization technique that allows to bring back more
than one type of objects in a single query. Prefetches are configured in terms of relationship
paths from the query root entity to the "prefetched" entity. E.g.:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-comment">// configure query with prefetches
</span>SelectQuery query = <span class="code-keyword">new</span> SelectQuery(Artist.class);
query.addPrefetch(<span class="code-quote">"paintingArray"</span>); 
<span class="code-comment">// execute query and <span class="code-keyword">do</span>
something with results
</span>List artists = context.performQuery(query);
Iterator it = artists.iterator();
<span class="code-keyword">while</span>(it.hasNext()) {
  Artist a = (Artist);
  <span class="code-object">System</span>.out.println(<span class="code-quote">"paintings:
"</span> + a.getPaintingArray().size());

<p>When prefetching is set, corresponding relationships are "inflated" with database
objects within a single <tt>performQuery</tt> run, leaving it up to Cayenne to
optimize retrieval of multiple entities. For instance the example above results in just two
SQL queries issued to the database internally, while running the same query without a prefetch
and later iterating over artists will result in <tt>1 + N</tt> queries, where
<tt>N</tt> is the number of artists returned. </p>

<h3><a name="Prefetching-PrefetchingHints"></a>Prefetching Hints</h3>

	<li>All types of relationships can be prefetched - to-one, to-many, flattened.</li>
	<li>A prefetch can span more than one relationship:
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
query.addPrefetch(<span class="code-quote">"paintingArray.toGallery"</span>);
	<li>A query can have more than one prefetch path at the same time:
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
query.addPrefetch(<span class="code-quote">"paintingArray"</span>); 
query.addPrefetch(<span class="code-quote">"paintingArray.toGallery"</span>);
	<li>If SelectQuery is fetching data rows, all default prefetches are ignored, though
custom joint prefetches (see below) will be included.</li>

<p><em>The rest of this page describes advanced use and can be skipped.</em></p>

<h3><a name="Prefetching-PrefetchSemantics"></a>Prefetch Semantics</h3>

<p>Queries store prefetching information as trees of <tt>PrefetchTreeNode</tt>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
PrefetchTreeNode treeRoot = query.getPrefetchTree();
<span class="code-keyword">if</span>(treeRoot != <span class="code-keyword">null</span>)
  <span class="code-comment">// <span class="code-keyword">do</span> something
with tree nodes

<p>Each node specifies the name of prefetch path segment and execution semantics. There
are two flavors of prefetch semantics - <b>joint</b> and <b>disjoint</b>.
Semantics of each node is initially determined by Cayenne when a new prefetch path is added,
and can be later customized by the user (e.g., see joint example below).</p>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td><p>In most cases prefetch
semantics is of no concern to the users. Cayenne will do its best to configure the right semantics
on the fly. Don't tweak semantics unless you understand the implications and have some proof
that different semantics would result in better select performance on your database. </p></td></tr></table></div>

<p>Some internal semantics rules:</p>

	<li>SelectQuery uses disjoint prefetches by default.</li>
	<li>SQLTemplate and ProcedureQuery use joint prefetches and can not use disjoint semantics
due to their nature.</li>
	<li>Prefetches with different semantics can be mixed freely within a query, as long
as there is no conflict with other rules.</li>

<h3><a name="Prefetching-DisjointPrefetches"></a>Disjoint Prefetches</h3>

<p>"Disjoint" prefetches (aka "normal prefetches", as this is how Cayenne implemented
prefetching since 1.0) internally result in a separate SQL statement per prefetch path.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
SelectQuery query = <span class="code-keyword">new</span> SelectQuery(Artist.class);

<span class="code-comment">// <span class="code-quote">"disjoint"</span>
is <span class="code-keyword">default</span> semantics of SelectQuery
</span>query.addPrefetch(<span class="code-quote">"paintingArray"</span>);

query.addPrefetch(<span class="code-quote">"paintingArray.toGallery"</span>);

<span class="code-comment">// <span class="code-keyword">this</span> will
result in 1 main SQL query plus 2 extra prefetch queries

<h3><a name="Prefetching-JointPrefetches"></a>Joint Prefetches</h3>

<p>"Joint" is prefetch type that issues a single SQL statement for multiple prefetch
paths. Cayenne processes in memory a cartesian product of the entities involved, converting
it to an object tree. SQLTemplate and ProcedureQuery create joint prefetches by default. SelectQuery
needs to be told to use joint prefetch:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-comment">// after adding a <span class="code-keyword">new</span>
prefetch, change its semantics to joint
</span>query.addPrefetch(<span class="code-quote">"paintingArray"</span>).setSemantics(


<p>Code above will result in a single SQL statement issued. OUTER joins will be used
for this type of prefetch. Specifics of the column naming when using prefetching with SQLTemplate
are discussed <a href="/confluence/display/CAYDOC/Advanced+SQLTemplate" title="Advanced

     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href=""
class="grey">Change Notification Preferences</a>

       <a href="">View
       <a href="">View
       <a href=";showCommentArea=true#addcomment">Add

View raw message