<?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>Ciarpame {.com} &#187; SQL</title>
	<atom:link href="http://www.ciarpame.com/tag/sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ciarpame.com</link>
	<description>Useful stuffs for the masses. Useless things for few.</description>
	<lastBuildDate>Tue, 01 Dec 2009 13:03:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4-alpha</generator>
		<item>
		<title>Accorciare e velocizzare le query SQL&#8230;si può!</title>
		<link>http://www.ciarpame.com/2008/10/23/accorciare-e-velocizzare-le-query-sqlsi-puo/</link>
		<comments>http://www.ciarpame.com/2008/10/23/accorciare-e-velocizzare-le-query-sqlsi-puo/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 09:00:01 +0000</pubDate>
		<dc:creator>Daniele Veratti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tricks]]></category>
		<category><![CDATA[INNER JOIN]]></category>
		<category><![CDATA[JOIN]]></category>
		<category><![CDATA[MySql]]></category>
		<category><![CDATA[NATURAL JOIN]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.ciarpame.com/?p=250</guid>
		<description><![CDATA[Spesso nello sviluppo di applicazioni, sia web che non, &#232; necessario appoggiarsi ad una base di dati. Una buona progettazione del database è talvolta fondamentale per ottenere buone prestazioni, sia per quanto riguarda la scrittura del codice, sia per quanto riguarda l&#8217;applicazione in sè. Prendiamo per esempio la tabella impiegati(id,cognome,nome,eta,dipartimento_id) e la tabella dipartimenti(id, nome_dipartimento,sede). [...]]]></description>
			<content:encoded><![CDATA[<p>Spesso nello sviluppo di applicazioni, sia web che non, &egrave; necessario appoggiarsi ad una base di dati. Una buona progettazione del database è talvolta fondamentale per ottenere buone prestazioni, sia per quanto riguarda la scrittura del codice, sia per quanto riguarda l&#8217;applicazione in sè.<br />
<span id="more-250"></span><br />
Prendiamo per esempio la tabella impiegati(id,cognome,nome,eta,dipartimento_id) e la tabella dipartimenti(id, nome_dipartimento,sede).</p>
<p>Se volessimo ottenere la lista degli impiegati il cui dipartimento ha, per esempio, sede a Roma, potremmo scrivere diverse query SQL che ci fanno ottenere lo stesso risultato:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> i<span style="color: #66cc66;">.*</span> <span style="color: #993333; font-weight: bold;">FROM</span> impiegati i<span style="color: #66cc66;">,</span>dipartimenti d 
<span style="color: #993333; font-weight: bold;">WHERE</span> i<span style="color: #66cc66;">.</span>dipartimento_id <span style="color: #66cc66;">=</span> d<span style="color: #66cc66;">.</span>id <span style="color: #993333; font-weight: bold;">AND</span> d<span style="color: #66cc66;">.</span>sede <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Roma'</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> impiegati 
<span style="color: #993333; font-weight: bold;">WHERE</span> dipartimento_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> id <span style="color: #993333; font-weight: bold;">FROM</span> dipartimenti <span style="color: #993333; font-weight: bold;">WHERE</span> sede <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Roma'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">SELECT</span> i<span style="color: #66cc66;">.*</span> <span style="color: #993333; font-weight: bold;">FROM</span> impiegati i 
<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> dipartimenti d <span style="color: #993333; font-weight: bold;">ON</span> i<span style="color: #66cc66;">.</span>dipartimento_id <span style="color: #66cc66;">=</span> d<span style="color: #66cc66;">.</span>id 
<span style="color: #993333; font-weight: bold;">WHERE</span> d<span style="color: #66cc66;">.</span>sede <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Roma'</span>;</pre></div></div>

<p>Tra le precedenti query l&#8217;ultima ha prestazioni decisamente migliori anche se è la più lunga da scrivere:<br />
nel primo caso il DBMS deve prima effettuare un prodotto cartesiano tra le due tabelle ed estrarre i record dove corrispondono gli ID dei dipartimenti e la sede è Roma;<br />
nel secondo caso il DBMS prima leggere tutti i dipartimenti con sede = &#8216;Roma&#8217; e per ogni impiegato verificare che dipartimento_id sia in questa lista.<br />
Nel terzo caso invece il DBMS automaticamente associa ogni impiegato con il dipartimento relativo e la ricerca sarà effettuata solo sul campo &#8220;sede&#8221;.<br />
L&#8217;uso di INNER JOIN velocizza le vostre applicazioni, ma usatelo con cautela: i valori nulli sui campi su cui si effettua il JOIN non sono ammessi.<br />
Se ve n&#8217;é la necessità si possono utilizzare LEFT e RIGHT JOIN.<br />
Se per esempio vogliamo sapere i cognomi degli impiegati che lavorano a Roma o che non lavorano (= dipartimento_id IS NULL) dovremmo scrivere:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> i<span style="color: #66cc66;">.</span>cognome <span style="color: #993333; font-weight: bold;">FROM</span> impiegati i 
<span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> dipartimenti d <span style="color: #993333; font-weight: bold;">ON</span> i<span style="color: #66cc66;">.</span>dipartimento_id <span style="color: #66cc66;">=</span> d<span style="color: #66cc66;">.</span>id 
<span style="color: #993333; font-weight: bold;">WHERE</span> sede <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Roma'</span> <span style="color: #993333; font-weight: bold;">OR</span> i<span style="color: #66cc66;">.</span>dipartimento_id <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NULL</span>;</pre></div></div>

<p>La scrittura delle INNER JOIN può diventare molto ripetitiva, soprattutto se vengono usate spesso. L&#8217;uso per di convenzioni però ci può dare una mano. Ridefiniamo le tabelle di prima in questo modo:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">impiegati <span style="color: #66cc66;">&#40;</span>impiegato_id<span style="color: #66cc66;">,</span> cognome<span style="color: #66cc66;">,</span> nome<span style="color: #66cc66;">,</span> eta<span style="color: #66cc66;">,</span> dipartimento_id<span style="color: #66cc66;">&#41;</span>
dipartimenti <span style="color: #66cc66;">&#40;</span>dipartimento_id<span style="color: #66cc66;">,</span> sede<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Con le tabelle definite in questa guisa possiamo sfoderare un ulteriore tipo di JOIN: il NATURAL JOIN.<br />
Il natural join utilizza campi con lo stesso nome per effettuare la combinazione dei record delle tabelle. Quindi se volessimo sapere quali impiegati lavorano a Roma, la nostra query SQL diventa:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> i<span style="color: #66cc66;">.*</span> <span style="color: #993333; font-weight: bold;">FROM</span> impiegati i <span style="color: #993333; font-weight: bold;">NATURAL</span> <span style="color: #993333; font-weight: bold;">JOIN</span> dipartimenti d <span style="color: #993333; font-weight: bold;">WHERE</span> d<span style="color: #66cc66;">.</span>sede <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Roma'</span>;</pre></div></div>

<p>Praticamente il NATURAL JOIN funziona esattamente come l&#8217;INNER JOIN, solo che ci fa risparmiare la scrittura di ON i.dipartimento_id = d.dipartimento_id, mantenendo inalterate le prestazioni.<br />
Quindi scegliendo bene i nomi dei campi possiamo scrivere query più veloci e più velocemente.</p>
<p>Ovviamente le prestazione delle JOIN aumentano in presenza di INDICI. Il miglior tipo di indice per effettuare un join è HASH, non implementato purtroppo da MySQL (almeno per quanto riguarda InnoDB e MyISAM).<br />
Infatti un indice implementato tramite HASH ha prestazioni migliori rispetto a BTREE se la ricerca viene effettuata in base a delle uguaglianze.</p>
<p>Gli indici BTREE invece hanno migliori prestazione in ricerche basate su range, come ad esempio nella query:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> impiegati <span style="color: #993333; font-weight: bold;">WHERE</span> eta <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">30</span></pre></div></div>

<p>Un indice BTREE sul campo &#8220;eta&#8221; migliorerebbe le prestazione della vostra query.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ciarpame.com/2008/10/23/accorciare-e-velocizzare-le-query-sqlsi-puo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

