<?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>Libre d'esprit &#187; performances</title>
	<atom:link href="http://libre-d-esprit.thinking-days.net/tag/performances/feed/" rel="self" type="application/rss+xml" />
	<link>http://libre-d-esprit.thinking-days.net</link>
	<description>Logiciels libres, joomla, talend, php, virtuemart, templates Joomla</description>
	<lastBuildDate>Sun, 21 Mar 2010 16:53:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Améliorer les performances de VirtueMart : Proposition d&#8217;une nouvelle table</title>
		<link>http://libre-d-esprit.thinking-days.net/2009/01/ameliorer-les-performances-de-virtuemart-proposition-dune-nouvelle-table/</link>
		<comments>http://libre-d-esprit.thinking-days.net/2009/01/ameliorer-les-performances-de-virtuemart-proposition-dune-nouvelle-table/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 17:48:41 +0000</pubDate>
		<dc:creator>Antoine</dc:creator>
				<category><![CDATA[Joomla]]></category>
		<category><![CDATA[VirtueMart]]></category>
		<category><![CDATA[performances]]></category>
		<guid isPermaLink="false">http://libre-d-esprit.thinking-days.net/?p=42</guid>
		<description><![CDATA[Voici une proposition permettant d&#8217;améliorer le parcours de l&#8217;arborescence catégorie de VirtueMart, au détriment de la vitesse d&#8217;écriture. Ce billet fait directement suite à mon article &#171;&#160;Améliorer les performances de VirtueMart&#171;&#160;.
Cette méthode nécessite de créer une nouvelle table que nous appellerons #__{vm}_category_tree, dont voici le schéma :
category_id : identifiant de la catégorie
category_path  : fil [...]]]></description>
			<content:encoded><![CDATA[<p>Voici une proposition permettant d&#8217;améliorer le parcours de l&#8217;arborescence catégorie de VirtueMart, au détriment de la vitesse d&#8217;écriture. Ce billet fait directement suite à mon article &laquo;&nbsp;<a href="http://libre-d-esprit.thinking-days.net/2009/01/ameliorer-les-performance-de-virtuemart/" target="_self">Améliorer les performances de VirtueMart</a>&laquo;&nbsp;.</p>
<p>Cette méthode nécessite de créer une nouvelle table que nous appellerons #__{vm}_category_tree, dont voici le schéma :</p>
<ul>
<li>category_id : identifiant de la catégorie</li>
<li>category_path  : fil d&#8217;ariane de la catégorie sous forme d&#8217;un liste dénormalisée d&#8217;identifiant de catégorie séparée par &laquo;&nbsp;,&nbsp;&raquo;</li>
<li>level : niveau de profondeur de la catégorie étudiée</li>
</ul>
<p>Par exemple,  une catégorie ayant un  &laquo;&nbsp;fil d&#8217;ariane&nbsp;&raquo; ayant pour valeur &laquo;&nbsp;,1,6,184,&nbsp;&raquo; serait de niveau 4 (étant donné qu&#8217;il existe trois niveaux de catégories parentes).  Sa catégorie parente serait la catégorie &laquo;&nbsp;184&#8243;  qui aurait elle même comme parent &laquo;&nbsp;6&#8243; qui aurait elle même comme parent &laquo;&nbsp;1&#8243; qui n&#8217;aurait pas de catégorie parente.</p>
<p>Le choix du séparateur &laquo;&nbsp;,&nbsp;&raquo; permettra d&#8217;utiliser au besoin la colonne presque directement dans une requête SQL via le mot clé &laquo;&nbsp;in&nbsp;&raquo; si besoin.</p>
<p>Voici le SQL permettant de créer cette table :</p>
<div class="codecolorer-container sql dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #ff0000;">`#__{vm}_category_tree`</span> <span style="color: #66cc66;">&#40;</span><br />
<span style="color: #ff0000;">`category_id`</span> int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
<span style="color: #ff0000;">`category_path`</span> varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
<span style="color: #ff0000;">`level`</span> int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
<span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`category_id`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`category_id`</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`category_path`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`category_path`</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`level`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`level`</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>MyISAM <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET<span style="color: #66cc66;">=</span>utf8;</div></div>
<p>Pour alimenter cette table, il faut d&#8217;abord executer une fois la requete suivante :</p>
<div class="codecolorer-container sql dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span><br />
<span style="color: #ff0000;">`#__{vm}_category_tree`</span><br />
<span style="color: #66cc66;">&#40;</span>category_id<span style="color: #66cc66;">,</span>category_path<span style="color: #66cc66;">,</span>level<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span><br />
<span style="color: #ff0000;">`#__{vm}_category.category_id`</span><span style="color: #66cc66;">,</span><br />
<span style="color: #ff0000;">&quot;,&quot;</span><span style="color: #66cc66;">,</span><br />
<span style="color: #cc66cc;">1</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span><br />
<span style="color: #ff0000;">`#__{vm}_category`</span><br />
<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span><br />
<span style="color: #ff0000;">`#__{vm}_category_xref`</span><br />
<span style="color: #993333; font-weight: bold;">ON</span><br />
<span style="color: #ff0000;">`#__{vm}_category_xref`</span><span style="color: #66cc66;">.</span>category_child_id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">`#__{vm}_category`</span><span style="color: #66cc66;">.</span>category_id<br />
<span style="color: #993333; font-weight: bold;">WHERE</span><br />
<span style="color: #ff0000;">`#__{vm}_category`</span><span style="color: #66cc66;">.</span>category_publish<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Y&quot;</span><br />
<span style="color: #993333; font-weight: bold;">AND</span><br />
<span style="color: #ff0000;">`#__{vm}_category_xref`</span><span style="color: #66cc66;">.</span>category_parent_id<span style="color: #66cc66;">=</span><span style="color: #cc66cc;">0</span>;</div></div>
<p>Il faut ensuite exécuter pour chaque niveau :</p>
<div class="codecolorer-container sql dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span><br />
<span style="color: #ff0000;">`#__{vm}_category_tree`</span><br />
<span style="color: #66cc66;">&#40;</span>category_id<span style="color: #66cc66;">,</span>category_path<span style="color: #66cc66;">,</span>level<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span><br />
<span style="color: #ff0000;">`#__{vm}_category`</span><span style="color: #66cc66;">.</span>category_id<span style="color: #66cc66;">,</span><br />
concat<span style="color: #66cc66;">&#40;</span>IFNULL<span style="color: #66cc66;">&#40;</span>parent_leaf<span style="color: #66cc66;">.</span>category_path<span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">`#__{vm}_category_xref`</span><span style="color: #66cc66;">.</span>category_parent_id<span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;;&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
IFNULL<span style="color: #66cc66;">&#40;</span>parent_leaf<span style="color: #66cc66;">.</span>level<span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span><br />
<span style="color: #ff0000;">`#__{vm}_category`</span><br />
<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span><br />
<span style="color: #ff0000;">`#__{vm}_category_xref`</span><br />
<span style="color: #993333; font-weight: bold;">ON</span><br />
<span style="color: #ff0000;">`#__{vm}_category_xref`</span><span style="color: #66cc66;">.</span>category_child_id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">`#__{vm}_category`</span><span style="color: #66cc66;">.</span>category_id<br />
<span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">OUTER</span> <span style="color: #993333; font-weight: bold;">JOIN</span><br />
<span style="color: #ff0000;">`#__{vm}_category_tree`</span> parent_leaf<br />
<span style="color: #993333; font-weight: bold;">ON</span><br />
parent_leaf<span style="color: #66cc66;">.</span>category_id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">`#__{vm}_category_xref`</span><span style="color: #66cc66;">.</span>category_parent_id<br />
<span style="color: #993333; font-weight: bold;">WHERE</span><br />
<span style="color: #ff0000;">`#__{vm}_category`</span><span style="color: #66cc66;">.</span>category_publish<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Y&quot;</span><br />
<span style="color: #993333; font-weight: bold;">AND</span><br />
<span style="color: #ff0000;">`#__{vm}_category_xref`</span><span style="color: #66cc66;">.</span>category_parent_id <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span><br />
category_id <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">`#__{vm}_category_tree`</span> <span style="color: #993333; font-weight: bold;">WHERE</span> level<span style="color: #66cc66;">=</span>?<span style="color: #66cc66;">&#41;</span></div></div>
<p>Le remplissage &laquo;&nbsp;au fil de l&#8217;eau&nbsp;&raquo; de cette table, fera l&#8217;objet d&#8217;autres billets.</p>
<p>Maintenant pour connaître tous les enfants directs et indirects d&#8217;une catégorie (&laquo;&nbsp;5&#8243; par exemple), il suffit d&#8217;éxécuter la requête suivante:</p>
<div class="codecolorer-container sql dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> category_id<span style="color: #66cc66;">,</span> level<br />
<br />
<span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">`#__{vm}_category_tree`</span><br />
<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> category_path <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">',5,%'</span>;</div></div>
<p>Une sacré économie de requetes SQL. Le résultat peut-être placée en cache si cela est possible. Il est également possible de complexifier cette requête en y rajoutant par exemple une jointure avec la table #__{vm}_category.</p>
<p><strong>Si vous êtes intéressé par cette modification, merci d’appuyer ma demande sur<a title="forum virtuemart" href="http://forum.virtuemart.net/index.php?topic=47713.0" target="_blank"> le forum</a>.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://libre-d-esprit.thinking-days.net/2009/01/ameliorer-les-performances-de-virtuemart-proposition-dune-nouvelle-table/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Améliorer les performance de Virtuemart : Constat</title>
		<link>http://libre-d-esprit.thinking-days.net/2009/01/ameliorer-les-performance-de-virtuemart/</link>
		<comments>http://libre-d-esprit.thinking-days.net/2009/01/ameliorer-les-performance-de-virtuemart/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 12:55:19 +0000</pubDate>
		<dc:creator>Antoine</dc:creator>
				<category><![CDATA[Joomla]]></category>
		<category><![CDATA[VirtueMart]]></category>
		<category><![CDATA[performances]]></category>
		<guid isPermaLink="false">http://libre-d-esprit.thinking-days.net/?p=6</guid>
		<description><![CDATA[Dans le cadre professionnel, il m&#8217;est arrivé à moi et à mes collèges de créer des boutiques en ligne, basées sur Joomla / VirtueMart, proposant plus de 15000 produits.
Après avoir réalisé des modifications nous permettant de tenir un tel catalogue, nous avons voulu les proposer à la communauté via le forum officiel de VirtueMart. Malheureusement, [...]]]></description>
			<content:encoded><![CDATA[<p>Dans le cadre professionnel, il m&#8217;est arrivé à moi et à mes collèges de créer des boutiques en ligne, basées sur Joomla / VirtueMart, proposant plus de 15000 produits.</p>
<p>Après avoir réalisé des modifications nous permettant de tenir un tel catalogue, nous avons voulu les proposer à la communauté via le forum officiel de VirtueMart. Malheureusement, étonnement, notre demande a été ignorée pendant plusieurs mois.</p>
<p>L&#8217;un des problèmes majeurs, était le nombre de requêtes SQL nécessaires aux parcours de l&#8217;arborescence VirtueMart.</p>
<p>L&#8217;arborescence produit est stocké dans la table #__vm_category_xref dont voici le schéma simplifié :</p>
<ul>
<li>category_parent_id : identifiant de la catégorie parent</li>
<li>category_child_id : identifiant de la catégorie enfant</li>
</ul>
<p>Imaginons que votre site soit découpé en catégories de la manière suivante :</p>
<ol>
<li>CMS
<ol>
<li>Joomla
<ol>
<li>Joomla 1.0</li>
<li>Joomla 1.5</li>
<li>Joomla 1.6</li>
</ol>
</li>
<li>Drupal</li>
<li>EZ Publish</li>
<li>Typo 3</li>
</ol>
</li>
<li>E-Commerce
<ol>
<li>VirtueMart</li>
<li>Magento</li>
<li>OS Commerce</li>
</ol>
</li>
</ol>
<p>Ce découpage est bien en dessous de l&#8217;arborescence que nous avons à gérer pour nos sites e-commerce.</p>
<p>Pour récupérer, l&#8217;arborescence et l&#8217;afficher il nous faut d&#8217;abord récupérer les catégories sans enfants (&laquo;&nbsp;CMS&nbsp;&raquo; et &laquo;&nbsp;E-Commerce&nbsp;&raquo;). Pour chacune de ces catégories, il faut voir si ces dernières ont des enfants et les afficher. Cet algorithme continue de manière itérative&#8230;</p>
<p>On voit bien que le nombre de requêtes SQL nécessaire est exponentiel. Certes, il y a le cache, mais ce dernier n&#8217;est pas toujours utilisable (ie : en back office).</p>
<p>Pire, imaginons que la page affichant la catégorie &laquo;&nbsp;CMS&nbsp;&raquo; doivent afficher l&#8217;ensemble des produits contenus dans la catégorie &laquo;&nbsp;CMS&nbsp;&raquo; et dans ces enfants directs et indirects, le tout trié par prix.</p>
<p>Ce problème explique en partie la lourdeur de l&#8217;arborescence du back-office par défaut de VirtueMart , lorsque le catalogue produit est volumineux.</p>
<p>J&#8217;expliquerais en détail la méthode que nous souhaitons soumettre à la communauté dans un prochain billet.</p>
]]></content:encoded>
			<wfw:commentRss>http://libre-d-esprit.thinking-days.net/2009/01/ameliorer-les-performance-de-virtuemart/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
