<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tony Thomas &#187; optimization</title>
	<atom:link href="http://anthonygthomas.com/tag/optimization/feed/" rel="self" type="application/rss+xml" />
	<link>http://anthonygthomas.com</link>
	<description>Father to two, husband to one, web developer and musician.</description>
	<lastBuildDate>Fri, 11 Nov 2011 14:00:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>CakePHP: Containable Behavior is Your Friend</title>
		<link>http://anthonygthomas.com/2010/02/18/cakephp-containable-behavior-is-your-friend/</link>
		<comments>http://anthonygthomas.com/2010/02/18/cakephp-containable-behavior-is-your-friend/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 16:21:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[containable behavior]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[behaviors]]></category>
		<category><![CDATA[containable]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://anthonygthomas.com/?p=369</guid>
		<description><![CDATA[When it comes to optimizing your CakePHP queries, you need to abandon Recursive and adopt Containable. In the example below I have the following models: Patient Specimen Result ResultType The associations in the model are: Result belongsTo ResultType hasMany Result Patient hasMany Result Specimen Specimen belongsTo Patient hasMany Result $paginate in the Result Controller Original [...]]]></description>
			<content:encoded><![CDATA[<p>When it comes to optimizing your CakePHP queries, you need to abandon Recursive and adopt Containable.</p>
<p>In the example below I have the following models:</p>
<ul>
<li>Patient</li>
<li>Specimen</li>
<li>Result</li>
<li>ResultType</li>
</ul>
<p>The associations in the model are:</p>
<ul>
<li>Result
<ul>
<li>belongsTo
<ul>
<li>ResultType
<ul>
<li>hasMany
<ul>
<li>Result</li>
</ul>
</li>
</ul>
</li>
<li>Patient
<ul>
<li>hasMany
<ul>
<li>Result</li>
<li>Specimen</li>
</ul>
</li>
</ul>
</li>
<li>Specimen
<ul>
<li>belongsTo
<ul>
<li>Patient</li>
</ul>
</li>
<li>hasMany
<ul>
<li>Result</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><span id="more-369"></span></p>
<h3>$paginate in the Result Controller</h3>
<h4>Original version</h4>
<pre class="brush: php; highlight: [12]; title: ; notranslate">var $paginate = array(
		'fields' =&gt; array(
			'ResultType.type',
			'Specimen.draw_date',
			'Result.id',
			'Result.patient_id',
			'Result.specimen_id',
			'Result.result',
			'Result.created',
			'Result.modified'
			),
		'recursive' =&gt; 0,
		'limit' =&gt; 50);</pre>
<h4>The Same Thing Using Containable</h4>
<pre class="brush: php; highlight: [11,12,13,14,15,16,17,18,19,20,21,22,23]; title: ; notranslate">var $paginate = array(
		'fields' =&gt; array(
			'id',
			'patient_id',
			'specimen_id',
			'result',
			'created',
			'modified'
			),
		'limit' =&gt; 50,
		'contain' =&gt; array(
			'ResultType' =&gt; array(
				'fields' =&gt; array(
					'ResultType.type',
					'ResultType.id'
					)
				),
			'Specimen' =&gt; array(
				'fields' =&gt; array(
					'Specimen.id',
					'Specimen.draw_date'
					)
				)
			)
		);</pre>
<h3>The SQL</h3>
<h4>SQL Generated from the Original $paginate var</h4>
<pre class="brush: sql; highlight: [7,8,19,20]; title: ; notranslate">SELECT COUNT(*) AS `count`
FROM `results` AS `Result`
LEFT JOIN `result_types` AS `ResultType`
ON (`Result`.`result_type_id` = `ResultType`.`id`)
LEFT JOIN `specimens` AS `Specimen`
ON (`Result`.`specimen_id` = `Specimen`.`id`)
LEFT JOIN `patients` AS `Patient`
ON (`Result`.`patient_id` = `Patient`.`id`)
WHERE 1 = 1

/* 1879 milliseconds */

SELECT `ResultType`.`type`, `Specimen`.`draw_date`, `Result`.`id`, `Result`.`patient_id`, `Result`.`specimen_id`, `Result`.`result`, `Result`.`created`, `Result`.`modified`
FROM `results` AS `Result`
LEFT JOIN `result_types` AS `ResultType`
ON (`Result`.`result_type_id` = `ResultType`.`id`)
LEFT JOIN `specimens` AS `Specimen`
ON (`Result`.`specimen_id` = `Specimen`.`id`)
LEFT JOIN `patients` AS `Patient`
ON (`Result`.`patient_id` = `Patient`.`id`)
WHERE 1 = 1
ORDER BY `Result`.`created` desc
LIMIT 50

/* 2106 milliseconds */</pre>
<h4>SQL Generated Using Containable Behavior</h4>
<pre class="brush: sql; title: ; notranslate">SELECT COUNT(*) AS `count`
FROM `results` AS `Result`
LEFT JOIN `result_types` AS `ResultType`
ON (`Result`.`result_type_id` = `ResultType`.`id`)
LEFT JOIN `specimens` AS `Specimen`
ON (`Result`.`specimen_id` = `Specimen`.`id`)
WHERE 1 = 1

/* 10 milliseconds */

SELECT `Result`.`id`, `Result`.`patient_id`, `Result`.`specimen_id`, `Result`.`result`, `Result`.`created`, `Result`.`modified`, `ResultType`.`type`, `ResultType`.`id`, `Specimen`.`id`, `Specimen`.`draw_date`
FROM `results` AS `Result`
LEFT JOIN `result_types` AS `ResultType`
ON (`Result`.`result_type_id` = `ResultType`.`id`)
LEFT JOIN `specimens` AS `Specimen`
ON (`Result`.`specimen_id` = `Specimen`.`id`)
WHERE 1 = 1
ORDER BY `Result`.`created` desc
LIMIT 50

/* 19 milliseconds */</pre>
<h3>The Difference</h3>
<p>The first set of queries took nearly 4 seconds. The second: 29 milliseconds. Containable just gives you so much more control over what&#8217;s selected in your query. Using <code>recursive =&gt; 0</code> still joined the patients table both times because it was associated in the model&#8211;even though in this case we didn&#8217;t need it. Using the Containable Behavior in the second example removed the patients table from the queries altogether.</p>
<p>This is one of the key pitfalls of using a framework like CakePHP; You can get things running quickly, but you have to go back and optimize. Otherwise you can build a heavy load on the server.</p>
<h3>Resources</h3>
<ul>
<li><a title="CakePHP Framework" href="http://cakephp.org" onclick="pageTracker._trackPageview('/outgoing/cakephp.org?referer=');">CakePHP</a></li>
<li><a href="http://book.cakephp.org/view/474/Containable" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/474/Containable?referer=');">The Containable Behavior</a></li>
<li><a title="The Recursive Model Attribute" href="http://book.cakephp.org/view/439/recursive" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/439/recursive?referer=');">The Recursive Model Attribute</a></li>
</ul>
<p><strong>Similar Posts:</strong>
<ul class="similar-posts">
<li><a href="http://anthonygthomas.com/2010/02/18/cakephp-containable-behavior-is-your-friend/" rel="bookmark" title="February 18, 2010">CakePHP: Containable Behavior is Your Friend</a></li>
<li><a href="http://anthonygthomas.com/2010/05/24/an-unexpected-problem-with-cakephp-and-email-elements/" rel="bookmark" title="May 24, 2010">An Unexpected Problem with CakePHP and Email Elements</a></li>
<li><a href="http://anthonygthomas.com/2008/12/10/use-functions-from-other-controllers-while-maintaining-mvc-architecture-in-cakephp/" rel="bookmark" title="December 10, 2008">Use Functions from Other Controllers While Maintaining MVC Architecture in CakePHP</a></li>
<li><a href="http://anthonygthomas.com/2008/11/26/getting-blueprint-css-javascript-libraries-into-your-cakephp-layout/" rel="bookmark" title="November 26, 2008">Getting Blueprint CSS &#038; JavaScript Libraries Into Your CakePHP Layout</a></li>
<li><a href="http://anthonygthomas.com/2009/05/22/roll-your-own-cakephp-components/" rel="bookmark" title="May 22, 2009">Roll Your Own CakePHP Components</a></li>
</ul>
<p><!-- Similar Posts took 11.645 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://anthonygthomas.com/2010/02/18/cakephp-containable-behavior-is-your-friend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

