<?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>kj187 &#187; MySQL</title>
	<atom:link href="http://blog.kj187.de/category/web/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.kj187.de</link>
	<description>Blog von Julian Kleinhans</description>
	<lastBuildDate>Sun, 22 Jan 2012 11:28:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.3</generator>
		<item>
		<title>TYPO3 Stellenangebot</title>
		<link>http://blog.kj187.de/2011/02/01/typo3-stellenangebot/</link>
		<comments>http://blog.kj187.de/2011/02/01/typo3-stellenangebot/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 09:53:01 +0000</pubDate>
		<dc:creator>Julian Kleinhans</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Privat]]></category>
		<category><![CDATA[TYPO3]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://blog.kj187.de/?p=268</guid>
		<description><![CDATA[Born to Code ? Die Bergisch Media GmbH ist seit 2005 Online-Marketing-Spezialist für die technische Konzeption und Realisierung professioneller Internet-Anwendungen für mittelständische Unternehmen und bietet ganzheitliche Lösungen in den Bereichen E-Commerce, Content-Management-Systeme, Konzeption und Design. Wir expandieren weiter und suchen zum nächstmöglichen Zeitpunkt eine/n engagierte/n TYPO3 Entwickler (m/w) Deine Aufgaben Technische Konzeption von kleinen bis [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>Born to Code ?</strong></em></p>
<p>Die Bergisch Media GmbH ist seit 2005 Online-Marketing-Spezialist für die technische Konzeption und Realisierung professioneller Internet-Anwendungen für mittelständische Unternehmen und bietet ganzheitliche Lösungen in den Bereichen E-Commerce, Content-Management-Systeme, Konzeption und Design.</p>
<p>Wir expandieren weiter und suchen zum nächstmöglichen Zeitpunkt eine/n engagierte/n</p>
<h2><strong>TYPO3 Entwickler (m/w)</strong></h2>
<p>Deine Aufgaben</p>
<ul>
<li>Technische Konzeption von kleinen bis großen TYPO3 Projekten</li>
<li>Entwicklung komplexer, individueller TYPO3 Projekte</li>
<li>Programmierung kundenspezifischer TYPO3 Extensions</li>
<li>Objektorientierte Programmierung (OOP) in PHP5 unter Verwendung von Design Patterns und Unit Tests</li>
</ul>
<p>Dein Profil</p>
<ul>
<li>2-3 Jahre Berufserfahrung in der Softwareentwicklung mit Internettechnologien</li>
<li>Außerordentlich hohe Internetaffinität</li>
<li>Umfangreiche TYPO3 Kenntnisse aus Entwicklersicht</li>
<li>Fundierte Kenntnisse in MySQL, HTML, CSS, PHP &amp; JavaScript</li>
<li>Sehr gute Kenntnisse in TypoScript</li>
<li>Sehr gute Kenntnisse in objektorientierter PHP Programmierung</li>
<li>Zuverlässigkeit</li>
<li>Pflichtbewusstsein</li>
</ul>
<p>Von Vorteil</p>
<ul>
<li>Erfahrung mit Extbase und Fluid</li>
<li>Erfahrung mit FLOW3</li>
<li>TYPO3 certified integrator</li>
</ul>
<p>Wir bieten dir</p>
<ul>
<li>Ein professionelles und modernes Arbeitsumfeld</li>
<li>Eine offene Unternehmenskultur mit flachen Hierarchien und schnellen Entscheidungswegen</li>
<li>Eine schnelle Verantwortungsübernahme und motiviertes Arbeiten in einem jungen, dynamischen Team</li>
</ul>
<p>Einsatzort: Heiligenhaus</p>
<p>Das brauchen wir von dir:<br />
Um einen ersten Eindruck von dir zu gewinnen, schicke uns bitte:</p>
<ul>
<li>Referenzen/Beispiele bereits durchgeführter TYPO3-Projekte</li>
<li>Aussagen über deine PHP-Kenntnisse (OO, PHP5 etc.)</li>
<li>Informationen zu deiner Person und deinem Werdegang (Lebenslauf)</li>
<li>Gehaltsvorstellungen</li>
<li>Informationen zum frühestmöglichen Eintrittstermins</li>
</ul>
<p>Ansprechpartner: Dennis van Almsick<br />
E-Mail: vanalmsick &#8211; at &#8211; bergisch-media &#8211; . &#8211; de<br />
URL: <a href="http://www.bergisch-media.de" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.bergisch-media.de?referer=');">http://www.bergisch-media.de</a></p>
<p>Impressionen &#8211; Verschaffe dir einen Überblick über unsere neuen Räumlichkeiten</p>

<a href='http://blog.kj187.de/2011/02/01/typo3-stellenangebot/165682_1877798423356_1193103733_32392656_71098_n/' title='Impression 1'><img width="150" height="150" src="http://blog.kj187.de/wp-content/uploads/2011/02/165682_1877798423356_1193103733_32392656_71098_n-150x150.jpg" class="attachment-thumbnail colorbox-268" alt="Impression 1" title="Impression 1" /></a>
<a href='http://blog.kj187.de/2011/02/01/typo3-stellenangebot/166839_1877794463257_1193103733_32392653_4550991_n/' title='Impression 2'><img width="150" height="150" src="http://blog.kj187.de/wp-content/uploads/2011/02/166839_1877794463257_1193103733_32392653_4550991_n-150x150.jpg" class="attachment-thumbnail colorbox-268" alt="Impression 2" title="Impression 2" /></a>
<a href='http://blog.kj187.de/2011/02/01/typo3-stellenangebot/167897_1877800103398_1193103733_32392658_6017522_n/' title='Impression 3'><img width="150" height="150" src="http://blog.kj187.de/wp-content/uploads/2011/02/167897_1877800103398_1193103733_32392658_6017522_n-150x150.jpg" class="attachment-thumbnail colorbox-268" alt="Impression 3" title="Impression 3" /></a>
<a href='http://blog.kj187.de/2011/02/01/typo3-stellenangebot/167979_1877808623611_1193103733_32392666_1789190_n/' title='Impression 4'><img width="150" height="150" src="http://blog.kj187.de/wp-content/uploads/2011/02/167979_1877808623611_1193103733_32392666_1789190_n-150x150.jpg" class="attachment-thumbnail colorbox-268" alt="Impression 4" title="Impression 4" /></a>
<a href='http://blog.kj187.de/2011/02/01/typo3-stellenangebot/168695_1877796663312_1193103733_32392655_4947876_n/' title='Impression 5'><img width="150" height="150" src="http://blog.kj187.de/wp-content/uploads/2011/02/168695_1877796663312_1193103733_32392655_4947876_n-150x150.jpg" class="attachment-thumbnail colorbox-268" alt="Impression 5" title="Impression 5" /></a>
<a href='http://blog.kj187.de/2011/02/01/typo3-stellenangebot/169002_1877815423781_1193103733_32392670_1934825_n/' title='Impression 6'><img width="150" height="150" src="http://blog.kj187.de/wp-content/uploads/2011/02/169002_1877815423781_1193103733_32392670_1934825_n-150x150.jpg" class="attachment-thumbnail colorbox-268" alt="Impression 6" title="Impression 6" /></a>

]]></content:encoded>
			<wfw:commentRss>http://blog.kj187.de/2011/02/01/typo3-stellenangebot/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL Optimierung</title>
		<link>http://blog.kj187.de/2010/03/16/mysql-optimierung/</link>
		<comments>http://blog.kj187.de/2010/03/16/mysql-optimierung/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 20:30:49 +0000</pubDate>
		<dc:creator>Julian Kleinhans</dc:creator>
				<category><![CDATA[Best practices]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Datenbank]]></category>
		<category><![CDATA[MySQL Optimierung]]></category>

		<guid isPermaLink="false">http://blog.kj187.de/?p=167</guid>
		<description><![CDATA[MySQL, es gehört zum Alltag eines jeden Webprogrammierers!
 Doch viele wissen nicht, bzw. achten nicht darauf, das man mit falschen Querys starke Perfomanceeinbußen fahren kann.
 Daher will ich euch ein paar Best Practices mit auf den Weg geben, die grundsätzlich für eine bessere Performance sorgen!]]></description>
			<content:encoded><![CDATA[<p><strong>MySQL</strong>, es gehört zum Alltag eines jeden Webprogrammierers!<br />
Doch viele wissen nicht, bzw. achten nicht darauf, das man mit falschen Querys starke Perfomanceeinbußen fahren kann.<br />
Daher will ich euch ein paar Best Practices mit auf den Weg geben, die grundsätzlich für eine bessere Performance sorgen!</p>
<p><strong>1) Vermeide SELECT * (sternchen)</strong></p>
<p>Über SELECT * werden <em>ALLE</em> Spalten einer Tabelle eingelesen! Aber nicht immer benötigt man wirklich alle Spalten aus einer Tabelle! Meißt benötigt man nur 2-3 Spalten wie den &#8220;title&#8221; oder die &#8220;id&#8221; und trotzem ist man zu faul die Spaltennamen auszuschreiben. Also knallen wir einfach mal das * (sternchen) hin, ist ja einfacher nicht wahr?! Jaha&#8230; nur bei einem * (sternchen) werden wie gesagt <em>ALLE</em> Spalten einer Tabelle eingelesen und das kostet Performance.<span id="more-167"></span></p>
<p>Benötigen wir also zum Beispiel aus einer Tabelle nur die Spalte &#8220;id&#8221; und &#8220;title&#8221; sollten wir unbedingt darauf achten auch nur diese beiden Spalten einzulesen:</p>
<pre class="brush: php;">// Nicht empfehlenswert
$result = mysql_query('SELECT * FROM tabelle WHERE id = 1');</pre>
<pre class="brush: php;">// Empfehlenswert
$result = mysql_query('SELECT id, title FROM tabelle WHERE id = 1');</pre>
<p><strong>2) Vermeide ORDER BY RAND()</strong></p>
<p>Ein sehr beliebtes Feature! Sie möchten auf Ihrer Webseite per Zufall &#8220;einen&#8221; Artikel aus Ihrer Tabelle darstellen!<br />
Was schreiben wir also, ganz easy:</p>
<pre class="brush: php;">$result = mysql_query('SELECT title FROM tabelle ORDER BY RAND() LIMIT 1');</pre>
<p>Sehr cool! Wir bekommen also per Zufall immer nur einen Artikel (eine Row), ganz wie wir es uns vorgestellt haben!<br />
Jedoch muss ich euch sagen, ORDER BY RANDOM() ernährt sich unheimlich gerne von unserer köstlichen und wertvollen Zutat namens Performance.  Wie also können wir unsere Abfrage so optimieren dass wir das gleiche Ergebnis bekommen ?</p>
<p>Ganz einfach, wir besorgen uns erstmal die Anzahl aller verfügbaren Zeilen, generieren uns dann eine Zufallszahl zwischen 0 und der Gesamtanzahl und nutzen LIMIT :-)</p>
<p>Moment, *taschenrechner.. klick klick*&#8230; hum, das sind ja jetzt mehr Zeilen als mein schöner Einzeiler da! Ja richtig, aber er frist garantiert nicht so viel Performance! Also, hier der Code:</p>
<pre class="brush: php;">$result = mysql_query('SELECT COUNT(*) FROM tabelle);
$row = mysql_fetch_row($result);
$randomizeNumber = mt_rand(0, $row[0]-1);
$result = mysql_query('SELECT title FROM tabelle LIMIT ' . $randomizeNumber . ', 1');</pre>
<p>Diese 4 Zeilen führen zum gleichen Ergebnis und sind nicht so Performancelastig.<br />
Hier wird gezielt per LIMIT nur eine Row gelesen. Bei ORDER BY RAND() werden erst ALLE Rows gelesen und dann erst per LIMIT begrenzt.</p>
<p><strong>3) Benutze LIMIT 1 bei eindeutigen Abfragen</strong></p>
<p>Es kommt sehr oft vor das wir genau wissen welche Zeile wir brauchen. Also schreibt man folgende Query</p>
<pre class="brush: php;">$result = mysql_query('SELECT title FROM tabelle WHERE title = &quot;Hello World&quot;');</pre>
<p>1 row in set (0.36 sec)</p>
<p>Wir wissen also daß wir nur eine Zeile zurückbekommen!<br />
Auch hier können wir ein minimale Performacesteigerung erzwingen, und wie ? Naja, wir wissen das es nur eine Zeile gibt, lasst uns also ein LIMIT 1 dran hängen:</p>
<pre class="brush: php;">$result = mysql_query('SELECT id, title, crdate FROM tabelle WHERE title = &quot;Hello World&quot; LIMIT 1');</pre>
<p>1 row in set (0.17 sec)</p>
<p>Auch wenn nicht wirklich spürbar, aber der Query ist schneller!<br />
Wenn wir nach einer Spalte suchen die einen Index hat, wie zB die Spalte id, diese ist ja unique, macht es keinen Sinn da über den Index das Ergebnis schon rasend schnell geliefert wird.</p>
<p><strong>4) Query Cache nutzen</strong></p>
<p>Seit MySQL Version 4 steht uns der MySQL Query Cache zur Verfügung der in den meisten Fällen unsere Abfragen beschleunigt. Vorausgesetzt ist natürlich das dieser aktiviert und konfiguriert ist! Die Betonung im ersten Satz liegt übrigens auf &#8220;in den meisten Fällen&#8221; ;-)</p>
<p>Was macht dieser Query Cache genau ?<br />
Hier werden Querys und deren Ergebnismengen abgespeichert. Wenn die gleiche Abfrage mehrmals benutzt wird und sich die betroffenen Datensätze nicht geändert haben, wird das Ergebnis aus diesem Cache geliefert anstatt eine neue Abfrage zu generieren.</p>
<p>Jetzt ist es so das wir als Programmierer eigentlich nichts spezielles beachten müssen. Unsere Querys landen eigentlich automatisch im Cache. Stop! Nicht immer! Nutzen wir in unserer Abfrage eine nichtdeterministische Funktion wird der Cache nicht benutzt!</p>
<p>Ok, halten wir mal kurz an! Ihr fragt euch jetzt bestimmt: &#8220;Was für eine Funktion ? nichtdeterwas ?&#8221; :-) hehe! Hier ein kleines Zitat aus der MySQL Doku:</p>
<blockquote><p>Eine Prozedur oder Funktion gilt als &#8220;deterministisch&#8221;, wenn sie für gleiche Eingabeparameter immer gleiche Resultate erzeugt; ansonsten ist sie &#8220;nichtdeterministisch&#8221;. Wenn in der Definition der Routine weder DETERMINISTIC noch NOT DETERMINISTIC steht, ist die Voreinstellung NOT DETERMINISTIC.</p></blockquote>
<p>Soweit klar ? Super&#8230; dann können wir ja weiter machen.<br />
Also, sobald wir eine solche Funktion in unserer Abfrage nutzen wird nicht mehr mit dem Cache gearbeitet! Soweit klar, hier ein Beispiel:</p>
<pre class="brush: php;">$result = mysql_query('SELECT title FROM tabelle WHERE myDate &lt;= CURDATE()');</pre>
<p>Mit diesem Query holen wir uns alle Zeilen wo die Spalte &#8220;myDate&#8221; kleiner gleich dem aktuellen Datum ist! CURDATE ist in diesem Fall eine nichtdeterministische Funktion! NOW() oder RAND() wären andere Beispiele!</p>
<p>Diesen Query können wir natürlich optimieren. Und zwar so das auch der Cache benutzt wird. Wir verzichten einfach auf diese komische nichtdeterministische Funktion und nutzen ein wenig PHP</p>
<pre class="brush: php;">$curdate = date('Y-m-d');
$result = mysql_query('SELECT title FROM tabelle WHERE date &lt;= ' . $curdate);</pre>
<p><strong>5) Nutze das Werkzeug EXPLAIN</strong></p>
<blockquote><p>Wenn man einer SELECT Anweisung das Schlüsselwort EXPLAIN voranstellt, zeigt MySQL Informationen des Optimierers zum Ausführungsplan der Abfrage an. MySQL erläutert also, wie es die SELECT-Anweisung verarbeiten würde, und gibt zudem an, wie und in welcher Reihenfolge Tabellen miteinander verknüpft werden.</p></blockquote>
<p>Zitat aus der MySQL Doku : <a href="http://dev.mysql.com/doc/refman/5.1/de/explain.html" onclick="pageTracker._trackPageview('/outgoing/dev.mysql.com/doc/refman/5.1/de/explain.html?referer=');">http://dev.mysql.com/doc/refman/5.1/de/explain.html</a></p>
<p>Super, bedeutet wir haben ein Werkzeug mit dessen Hilfe wir Step by Step einen SELECT Query optimieren können!</p>
<p>Wir können jetzt also beim entwickeln unserer Applikation jedes mal wenn wir einen SELECT bauen direkt schauen ob dieser performant ist! Da wir die Applikation ja gerade erst bauen, die Datenbank nur ein paar Testeinträge besitzt, geht alles in allem recht flot und wir stempeln unseren Query als Performant ab!</p>
<p>1 Jahr später, die Applikation ist gut besucht, die Datenbank ist fett mit wunderbaren Informationen gefüllt, fragen wir uns, warum ist meine Webseite so langsam. Als ich die gebaut hab war doch alles so schnell. Mit der Zeit hat sich viel verändert, als wir beim entwickeln getestet haben hatten wir auch noch keinen Bezug auf die Realität, keine volle Datenbank, keine X-hundert Hits am Tag!</p>
<p>Wir wollen also versuchen unsere Webseite im MySQL Bereich zu optimieren. Um jetzt nicht jede einzelne Query wieder zu suchen und von Hand zu testen nutzen wir ein wunderbares Feature! Wir können MySQL sagen ab welcher Ausführungszeit eine Abfrage als &#8220;zu langsam&#8221; gilt. Und diese lassen wir dann mitloggen! Extrem cool nicht war.. wir haben also jetzt eine Möglichkeit Querys ausfindig zu machen die langsam sind. Diese nehmen wir uns jetzt genauer unter die Lupe und zwar mit unserem Werkzeug EXPLAIN!</p>
<p>EXPLAIN analysiert unsere Abfrage und stellt dar was die Datenbank mit der Abfrage genau macht.<br />
Beispiel:</p>
<pre class="brush: php;">$result = mysql_query('EXPLAIN SELECT title FROM tabelle');</pre>
<p>Was uns das Ergebnis genau sagt können wir auf der MySQL Seite nachlesen: <a href="http://dev.mysql.com/doc/refman/5.1/de/explain.html" onclick="pageTracker._trackPageview('/outgoing/dev.mysql.com/doc/refman/5.1/de/explain.html?referer=');">http://dev.mysql.com/doc/refman/5.1/de/explain.html</a> eine ausführliche Antwort um dieses zu verstehen würde sonst diesen Beitrag sprengen :-)</p>
<p><strong>6) Suchfelder indizieren</strong></p>
<p>Oft müssen wir per MySQL nach irgendwelchen Sachen suchen. Nehmen wir an, wir haben einen selbstprogrammierten Blog. Der User möchte nach einem Artikel suchen wo er sich nur schwach an den Titel erinnern kann. Irgendwas mit &#8220;Hello&#8221; war das&#8230;.</p>
<p>Statisch umgesetzt könnte das so aussehen:</p>
<pre class="brush: php;">$result = mysql_query('SELECT COUNT(*) FROM tabelle WHERE title LIKE &quot;Hello%&quot;');</pre>
<p>Wenn wir uns die Zeit dazu mal anschauen sehen wir das das schon ziemlich lange dauert: 1 row in set (0.31 sec)</p>
<p>Also, legen wir einen INDEX auf die Spalte &#8220;title&#8221; in der gesucht werden soll:</p>
<p>[mysql]ALTER TABLE tabelle ADD INDEX (&#8220;title&#8221;);[/mysql]</p>
<p>Führen wir unseren Query erneut aus:</p>
<pre class="brush: php;">$result = mysql_query('SELECT COUNT(*) FROM tabelle WHERE title LIKE &quot;Hello%&quot;');</pre>
<p>sieht unser Ergebnis schon ganz anders aus: 1 row in set (0.07 sec)</p>
<p>Mit einem INDEX kann man also extreme Performancesteigerungen erreichen!</p>
<p>Kleiner Tip: Wo welcher Index verwendet wird können wir ganz einfach mit der Abfrage</p>
<pre class="brush: sql;">SHOW INDEX FROM tabelle;</pre>
<p>rausbekommen!</p>
<p>Es gibt bestimmt noch dutzende weitere Möglichkeiten seine Scripte zu optimieren! Ich möchte hier aber erst mal einen Cut machen. Wenn Ihr noch gute Optimierungsmöglichkeiten kennt die ich hier mit aufnehmen sollte, benutzt bitte die Kommentarfunktion!</p>
<p>Jedenfalls hoffe ich das euch der Artikel gefallen und vor allem geholfen hat! Ihr könnt diesen Artikel auch unten Bewerten oder per Twitter ein wenig pushen :-)</p>
<p>Lieben Gruß<br />
Julian</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kj187.de/2010/03/16/mysql-optimierung/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

