<?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>Julius Beckmann &#187; MySQL</title>
	<atom:link href="http://juliusbeckmann.de/blog/category/mysql/feed" rel="self" type="application/rss+xml" />
	<link>http://juliusbeckmann.de/blog</link>
	<description>Ich bin nicht verrückt, nur technisch begabt ...</description>
	<lastBuildDate>Tue, 07 Sep 2010 18:34:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PHP/MySQL: Warning: mysql_query(): Unable to save result set ...</title>
		<link>http://juliusbeckmann.de/blog/php-mysql-warning-mysql_query-unable-to-save-result-set.html</link>
		<comments>http://juliusbeckmann.de/blog/php-mysql-warning-mysql_query-unable-to-save-result-set.html#comments</comments>
		<pubDate>Mon, 18 Jan 2010 15:08:36 +0000</pubDate>
		<dc:creator>Julius</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Error]]></category>
		<category><![CDATA[Query]]></category>
		<category><![CDATA[Solution]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://juliusbeckmann.de/blog/?p=507</guid>
		<description><![CDATA[Today i found a error in a tiny script i was working on.
The error Message looked like this:
Warning: mysql_query() [function.mysql-query]: Unable to save result set in /var/www/example.php on line 55
First i found a few hints about repairing or optimizing MySQL tables, but this did not work out.
After a few debugging outputs a realized that the [...]]]></description>
			<content:encoded><![CDATA[<p>Today i found a error in a tiny script i was working on.<br />
The error Message looked like this:</p>
<div class="codesnip-container" >Warning: mysql_query() [function.mysql-query]: Unable to save result set in /var/www/example.php on line 55</div>
<p>First i found a few hints about repairing or optimizing MySQL tables, but this did not work out.<br />
After a few debugging outputs a realized that the query was not properly written.<br />
<span id="more-507"></span><br />
The original query looked like this:</p>
<div class="codesnip-container" >
<div class="sql codesnip" style="font-family:monospace;"><span class="kw1">SELECT</span> id<br />
<span class="kw1">FROM</span> <span class="st0">`table`</span> <br />
<span class="kw1">WHERE</span> <span class="st0">`order`</span> <span class="sy0">&gt;</span><br />
<span class="br0">&#40;</span><br />
&nbsp; <span class="kw1">SELECT</span> <span class="st0">`order`</span> <br />
&nbsp; <span class="kw1">FROM</span> <span class="st0">`table`</span> <br />
&nbsp; <span class="kw1">WHERE</span> active <span class="sy0">=</span> 1<br />
<span class="br0">&#41;</span><br />
<span class="kw1">LIMIT</span> <span class="nu0">1</span>;</div>
</div>
<p>As you can see the query as a non correlated subquery. It worked fine nearly all the time, but only when the subquery returns only zero or one lines. If there are more lines MySQL generates the "Unable to save result set", because `order` cant be bigger then 2 resultvalues at the same time.<br />
The right query looks like this:</p>
<div class="codesnip-container" >
<div class="sql codesnip" style="font-family:monospace;"><span class="kw1">SELECT</span> id<br />
<span class="kw1">FROM</span> <span class="st0">`table`</span> <br />
<span class="kw1">WHERE</span> <span class="st0">`order`</span> <span class="sy0">&gt;</span><br />
<span class="br0">&#40;</span><br />
&nbsp; <span class="kw1">SELECT</span> <span class="st0">`order`</span> <br />
&nbsp; <span class="kw1">FROM</span> <span class="st0">`table`</span> <br />
&nbsp; <span class="kw1">WHERE</span> active <span class="sy0">=</span> 1<br />
&nbsp; <span class="kw1">LIMIT</span> 1<br />
<span class="br0">&#41;</span><br />
<span class="kw1">LIMIT</span> <span class="nu0">1</span>;</div>
</div>
<p>A extra LIMIT 1 makes the deal perfect, and saved a little bit of my day.</p>
]]></content:encoded>
			<wfw:commentRss>http://juliusbeckmann.de/blog/php-mysql-warning-mysql_query-unable-to-save-result-set.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Benchmark: APC vs. MySQL MEMORY fetching Speed</title>
		<link>http://juliusbeckmann.de/blog/benchmark-apc-vs-mysql-memory-fetching-speed.html</link>
		<comments>http://juliusbeckmann.de/blog/benchmark-apc-vs-mysql-memory-fetching-speed.html#comments</comments>
		<pubDate>Wed, 02 Sep 2009 15:07:44 +0000</pubDate>
		<dc:creator>Julius</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[APC]]></category>
		<category><![CDATA[Benchmark]]></category>

		<guid isPermaLink="false">http://juliusbeckmann.de/blog/?p=409</guid>
		<description><![CDATA[I once wrote a article about APC and MySQL MEMORY table caching and found out that APC needs very much memory compared to MySQL MEMORY. Now i did a short benchmark to check out the fetching speed of these two solutions with a interesting result.

Script
First, the benchmark script:

&#60;?php
// Simple test script benchmarking cache access times
// [...]]]></description>
			<content:encoded><![CDATA[<p>I once wrote a article about <a href="/blog/php-apc-oder-mysql-memory-table-fuer-temporaeren-cache.html">APC and MySQL MEMORY table caching</a> and found out that APC needs very much memory compared to MySQL MEMORY. Now i did a short benchmark to check out the fetching speed of these two solutions with a interesting result.<br />
<span id="more-409"></span></p>
<h3>Script</h3>
<p>First, the benchmark script:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span></p>
<p><span class="co1">// Simple test script benchmarking cache access times</span><br />
<span class="co1">// of APC and MySQL MEMORY</span><br />
<span class="co1">// by: Julius Beckmann (juliusbeckmann.de)</span></p>
<p><span class="co1">// Config</span><br />
<span class="re0">$n</span> <span class="sy0">=</span> <span class="nu0">10000</span><span class="sy0">;</span><br />
<span class="re0">$newline</span> <span class="sy0">=</span> <span class="st0">&quot;&lt;br/&gt;<span class="es1">\n</span>&quot;</span><span class="sy0">;</span></p>
<p><span class="co1">// Init benchmark array with $n entrys</span><br />
<span class="re0">$array</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$i</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">++</span> <span class="sy0">&lt;</span> <span class="re0">$n</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; <span class="re0">$array</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <a href="http://www.php.net/rand"><span class="kw3">rand</span></a><span class="br0">&#40;</span>0<span class="sy0">,</span>999999<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="kw1">echo</span> <span class="st0">&quot;Testarray has &quot;</span><span class="sy0">.</span><a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$array</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="st0">&quot; random integer entrys&quot;</span><span class="sy0">.</span><span class="re0">$newline</span><span class="sy0">;</span></p>
<p>
<span class="co1">// Check direct array access time</span><br />
<span class="re0">$time_start</span> <span class="sy0">=</span> <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$i</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$i</span> <span class="sy0">&lt;</span> <span class="re0">$n</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; <span class="re0">$devnull</span> <span class="sy0">=</span> <span class="re0">$array</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#93;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<span class="re0">$time_end</span> <span class="sy0">=</span> <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$time</span> <span class="sy0">=</span> <span class="re0">$time_end</span><span class="sy0">-</span><span class="re0">$time_start</span><span class="sy0">;</span><br />
<span class="kw1">echo</span> <a href="http://www.php.net/number_format"><span class="kw3">number_format</span></a><span class="br0">&#40;</span><span class="re0">$time</span><span class="sy0">,</span> <span class="nu0">3</span><span class="sy0">,</span> <span class="st_h">'.'</span><span class="sy0">,</span> <span class="st_h">''</span><span class="br0">&#41;</span><br />
&nbsp; <span class="sy0">.</span><span class="st0">&quot; seconds - direct array access&quot;</span><span class="sy0">.</span><span class="re0">$newline</span><span class="sy0">;</span><br />
&nbsp; </p>
<p><span class="co1">// Adding these array values to APC</span><br />
<span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$array</span> <span class="kw1">as</span> <span class="re0">$k</span> <span class="sy0">=&gt;</span> <span class="re0">$v</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; apc_store<span class="br0">&#40;</span><span class="st_h">'test_'</span><span class="sy0">.</span><span class="re0">$k</span><span class="sy0">,</span> <span class="re0">$v</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<span class="co1">// Benchmarking apc_fetch</span><br />
<span class="re0">$time_start</span> <span class="sy0">=</span> <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$i</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="re0">$count</span> <span class="sy0">=</span> <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$array</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$i</span> <span class="sy0">&lt;</span> <span class="re0">$count</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; <span class="re0">$devnull</span> <span class="sy0">=</span> apc_fetch<span class="br0">&#40;</span><span class="st_h">'test_'</span><span class="sy0">.</span><span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<span class="re0">$time_end</span> <span class="sy0">=</span> <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$time</span> <span class="sy0">=</span> <span class="re0">$time_end</span><span class="sy0">-</span><span class="re0">$time_start</span><span class="sy0">;</span><br />
<span class="kw1">echo</span> <a href="http://www.php.net/number_format"><span class="kw3">number_format</span></a><span class="br0">&#40;</span><span class="re0">$time</span><span class="sy0">,</span> <span class="nu0">3</span><span class="sy0">,</span> <span class="st_h">'.'</span><span class="sy0">,</span> <span class="st_h">''</span><span class="br0">&#41;</span><br />
&nbsp; <span class="sy0">.</span><span class="st0">&quot; seconds - apc_fetch()&quot;</span><span class="sy0">.</span><span class="re0">$newline</span><span class="sy0">;</span><br />
<span class="co1">// Deleting APC entrys</span><br />
<span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$array</span> <span class="kw1">as</span> <span class="re0">$k</span> <span class="sy0">=&gt;</span> <span class="re0">$v</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; apc_delete<span class="br0">&#40;</span><span class="st_h">'test_'</span><span class="sy0">.</span><span class="re0">$k</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></p>
<p>
<span class="co1">// Benchmark mysql</span></p>
<p><span class="co1">// Connect</span><br />
<span class="re0">$link</span> <span class="sy0">=</span> <a href="http://www.php.net/mysql_connect"><span class="kw3">mysql_connect</span></a><span class="br0">&#40;</span><span class="st_h">'localhost'</span><span class="sy0">,</span> <span class="st_h">'username'</span><span class="sy0">,</span> <span class="st_h">'password'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$link</span><span class="br0">&#41;</span> <a href="http://www.php.net/die"><span class="kw3">die</span></a><span class="br0">&#40;</span><span class="st_h">'Not connected : '</span> <span class="sy0">.</span> <a href="http://www.php.net/mysql_error"><span class="kw3">mysql_error</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$db_selected</span> <span class="sy0">=</span> <a href="http://www.php.net/mysql_select_db"><span class="kw3">mysql_select_db</span></a><span class="br0">&#40;</span><span class="st_h">'database'</span><span class="sy0">,</span> <span class="re0">$link</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$db_selected</span><span class="br0">&#41;</span> <a href="http://www.php.net/die"><span class="kw3">die</span></a> <span class="br0">&#40;</span><span class="st_h">'Can\'t use foo : '</span> <span class="sy0">.</span> <a href="http://www.php.net/mysql_error"><span class="kw3">mysql_error</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <br />
<span class="co1">// Adding these array values to mySQL Memory table</span><br />
<span class="coMULTI">/* TABLE:<br />
&nbsp;CREATE TABLE `test_memory` (<br />
`key` INT UNSIGNED NOT NULL ,<br />
`value` INT UNSIGNED NOT NULL<br />
) ENGINE = MEMORY <br />
*/</span><br />
<span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$array</span> <span class="kw1">as</span> <span class="re0">$k</span> <span class="sy0">=&gt;</span> <span class="re0">$v</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; <a href="http://www.php.net/mysql_query"><span class="kw3">mysql_query</span></a><span class="br0">&#40;</span><span class="st_h">'INSERT INTO test_memory (`key`,`value`) VALUES ('</span><span class="sy0">.</span><span class="re0">$k</span><span class="sy0">.</span><span class="st_h">', '</span><span class="sy0">.</span><span class="re0">$v</span><span class="sy0">.</span><span class="st_h">');'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<span class="co1">// Benchmark mysql memory table</span><br />
<span class="re0">$time_start</span> <span class="sy0">=</span> <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$i</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="re0">$count</span> <span class="sy0">=</span> <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$array</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$i</span> <span class="sy0">&lt;</span> <span class="re0">$count</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; <a href="http://www.php.net/list"><span class="kw3">list</span></a><span class="br0">&#40;</span><span class="sy0">,</span><span class="re0">$devnull</span><span class="br0">&#41;</span> <span class="sy0">=</span> <a href="http://www.php.net/mysql_fetch_row"><span class="kw3">mysql_fetch_row</span></a><span class="br0">&#40;</span><a href="http://www.php.net/mysql_query"><span class="kw3">mysql_query</span></a><span class="br0">&#40;</span><span class="st_h">'SELECT * FROM `test_memory` WHERE `key` ='</span><span class="sy0">.</span><span class="re0">$i</span><span class="sy0">++.</span><span class="st_h">';'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<span class="re0">$time_end</span> <span class="sy0">=</span> <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$time</span> <span class="sy0">=</span> <span class="re0">$time_end</span><span class="sy0">-</span><span class="re0">$time_start</span><span class="sy0">;</span><br />
<span class="kw1">echo</span> <a href="http://www.php.net/number_format"><span class="kw3">number_format</span></a><span class="br0">&#40;</span><span class="re0">$time</span><span class="sy0">,</span> <span class="nu0">3</span><span class="sy0">,</span> <span class="st_h">'.'</span><span class="sy0">,</span> <span class="st_h">''</span><span class="br0">&#41;</span><br />
&nbsp; <span class="sy0">.</span><span class="st0">&quot; seconds - mysql_query from MEMORY table FIRST RUN&quot;</span><span class="sy0">.</span><span class="re0">$newline</span><span class="sy0">;</span><br />
<span class="co1">// Benchmark a second time to check for mysql caches</span><br />
<span class="re0">$time_start</span> <span class="sy0">=</span> <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$i</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="re0">$count</span> <span class="sy0">=</span> <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$array</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$i</span> <span class="sy0">&lt;</span> <span class="re0">$count</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; <a href="http://www.php.net/list"><span class="kw3">list</span></a><span class="br0">&#40;</span><span class="sy0">,</span><span class="re0">$devnull</span><span class="br0">&#41;</span> <span class="sy0">=</span> <a href="http://www.php.net/mysql_fetch_row"><span class="kw3">mysql_fetch_row</span></a><span class="br0">&#40;</span><a href="http://www.php.net/mysql_query"><span class="kw3">mysql_query</span></a><span class="br0">&#40;</span><span class="st_h">'SELECT * FROM `test_memory` WHERE `key` ='</span><span class="sy0">.</span><span class="re0">$i</span><span class="sy0">++.</span><span class="st_h">';'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<span class="re0">$time_end</span> <span class="sy0">=</span> <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$time</span> <span class="sy0">=</span> <span class="re0">$time_end</span><span class="sy0">-</span><span class="re0">$time_start</span><span class="sy0">;</span><br />
<span class="kw1">echo</span> <a href="http://www.php.net/number_format"><span class="kw3">number_format</span></a><span class="br0">&#40;</span><span class="re0">$time</span><span class="sy0">,</span> <span class="nu0">3</span><span class="sy0">,</span> <span class="st_h">'.'</span><span class="sy0">,</span> <span class="st_h">''</span><span class="br0">&#41;</span><br />
&nbsp; <span class="sy0">.</span><span class="st0">&quot; seconds - mysql_query from MEMORY table SECOND RUN&quot;</span><span class="sy0">.</span><span class="re0">$newline</span><span class="sy0">;</span><br />
<span class="co1">// Trunc memory table </span><br />
<a href="http://www.php.net/mysql_query"><span class="kw3">mysql_query</span></a><span class="br0">&#40;</span><span class="st_h">'TRUNCATE TABLE test_memory;'</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="sy1">?&gt;</span></div>
</div>
<h3>Result</h3>
<p>Output of the script:</p>
<div class="codesnip-container" >Testarray has 10000 random integer entrys<br />
0.002 seconds - direct array access<br />
0.011 seconds - apc_fetch()<br />
1.304 seconds - mysql_query from MEMORY table FIRST RUN<br />
1.167 seconds - mysql_query from MEMORY table SECOND RUN</div>
<p>The measured times are <strong>only</strong> fetching times. Fetching should by done much often in reality than storing, so it is way more important.</p>
<p>As you can see the direct access is the fastes. APC is ony 5 times slower than direct access. That is very fast compared to the MySQL equivalent. MySQL took about 100 times longer than APC. This result is astonishing. I though MySQL might be about 5 or 10 times slower then APC, but 100 is very much.<br />
I also let the MySQL select run twice to check for buffers that might come in but no better result.<br />
A "stangl" already mentioned, the overhead produced by MySQL for querying, parsing, and returning is very big and slow compared to APC.</p>
<h3>Conclusion</h3>
<p>If you need only very few variables to store, try APC first. MEMORY TABLES might be handy when you need to save more than APC can handle effictively.</p>
<p>If anybody can find a mistake i did, please let me know. Maybe MEMORY tables are not that slow as my benchmark turned out.</p>
]]></content:encoded>
			<wfw:commentRss>http://juliusbeckmann.de/blog/benchmark-apc-vs-mysql-memory-fetching-speed.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP - APC oder MySQL MEMORY Table für temporären Cache?</title>
		<link>http://juliusbeckmann.de/blog/php-apc-oder-mysql-memory-table-fuer-temporaeren-cache.html</link>
		<comments>http://juliusbeckmann.de/blog/php-apc-oder-mysql-memory-table-fuer-temporaeren-cache.html#comments</comments>
		<pubDate>Wed, 12 Aug 2009 08:45:33 +0000</pubDate>
		<dc:creator>Julius</dc:creator>
				<category><![CDATA[APC]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Benchmark]]></category>
		<category><![CDATA[Caching]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://juliusbeckmann.de/blog/?p=367</guid>
		<description><![CDATA[Bei einem aktuellen Projekt wurde APC eingesetzt um tausende kleinere Variablen zu cachen da es sich nicht lohnen würde diese in einer persistenten Datenbank zu speichern. Da der 30MB große APC Cache jedoch recht schnell voll wurde habe ich ein paar Nachforschungen angestellt, dabei bin ich zu dem Schluss gekommen dass APC für das Speichern [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://juliusbeckmann.de/blog/static/mysql_logo.jpg"><img src="http://juliusbeckmann.de/blog/static/mysql_logo-200x116.jpg" alt="mysql_logo" title="mysql_logo" width="200" height="116" class="alignright size-thumbnail wp-image-374" /></a>Bei einem aktuellen Projekt wurde APC eingesetzt um tausende kleinere Variablen zu cachen da es sich nicht lohnen würde diese in einer persistenten Datenbank zu speichern. Da der 30MB große APC Cache jedoch recht schnell voll wurde habe ich ein paar Nachforschungen angestellt, dabei bin ich zu dem Schluss gekommen dass APC für das Speichern von einzelnen kleinen Variablen viel zu viel Speicher verschwendet.<br />
<span id="more-367"></span></p>
<h2>Code - APC Test</h2>
<p>Um zu testen wie viele Variablen in den 30 MB großen SHM Cache von APC passen haben ich in einer Schleife wie dieser einfach den ganzen Speicher vollgeschrieben:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="re0">$i</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">++</span> <span class="sy0">&amp;</span>gt<span class="sy0">;=</span> 0<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="sy0">!</span>apc_store<span class="br0">&#40;</span><span class="st_h">'test_'</span><span class="sy0">.</span><span class="re0">$i</span><span class="sy0">,</span> <span class="re0">$i</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">echo</span> <span class="st0">&quot;Could save <span class="es4">$i</span> variables in 30 MB APC Cache<span class="es1">\n</span>&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="re0">$i</span> <span class="sy0">=</span> <span class="sy0">-</span><span class="nu0">1</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>Das Script hat mir ausgegeben dass rund 151000 Variablen gespeichert werden konnten. Das heißt jede Variable hat rund 207 Byte Speicher verbraucht (!). Dafür dass nur ein simpler Integer gespeichert wurde ist dies verdammt viel.</p>
<h2>Alternative: MySQL MEMORY Tabelle</h2>
<p>Eine Mögliche Alternative die mir in den Sinn kam war die MySQL MEMORY Engine welche seine Daten im RAM des Computers lässt und keine Schreiboperationen auf der Festplatte ausführt. Diese MEMORY Tabellen sind auch in ihrer Größe beschränkt welche per Default meist bei 16 MB liegt.</p>
<p>Als Tabellenstruktur habe ich etwa folgende gewählt:</p>
<div class="codesnip-container" >
<div class="sql codesnip" style="font-family:monospace;"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> memory_test <span class="br0">&#40;</span><br />
<span class="st0">`user_id`</span> integer<span class="br0">&#40;</span>10<span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span><br />
<span class="st0">`user_data`</span> integer<span class="br0">&#40;</span>10<span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><br />
<span class="br0">&#125;</span> ENGINE<span class="sy0">=</span>MEMORY;</div>
</div>
<p>Nach dem Einfügen des ersten Datensatzes wir die Tabelle 124 KB groß, doch dies ändert sich bis bei mir aktuell 3300 Einträge nicht. Die MySQL MEMORY Engine scheint Blöcke a 124 KB zu reservieren.<br />
Nach dem Einfügen von 3000 Einträgen ist die Tabelle immernoch 124 KB groß was für mich bedeutet dass in der MEMORY Tabelle ein Datensatz weniger als 40 Byte verbraucht.</p>
<h2>Vergleich</h2>
<p>Der Vergleich zwischen 207 Byte in APC und &lt; 40 Byte in MySQL MEMORY spricht für sich. Da die Zugriffsgeschwindigkeit in APC und MySQL MEMORY etwa gleich schnell ist sollte man wenn man die Möglichkeit hat MEMORY Tabellen zu benutzen dies auch machen.<br />
Es wäre vielleicht ratsam um die apc_* Funktionen andere Wrapper Funktionen zu schreiben so dass man diese im Fall eines Wechsels von APC zu MEMORY einfach austauschen kann.</p>
<h2>Stolpersteine</h2>
<p>Es gibt jedoch auch kleine Stolpersteine die rumliegen können:</p>
<ul>
<li> apc_store() bietet es an eine ttl (Time To Live) mitzugeben nach dem der Cache-Eintrag verfallen soll. Dies ist in einer MEMORY Tabelle mit einer extra Spalte mit einem Timestamp zu realisieren welche zwar wieder Speicher verbraucht, aber wir sicherlich immer noch unter den 207 Byte von APC bleiben.</li>
</ul>
<ul>
<li> Der Zugriff in einer MEMORY Tabelle ist auch <strong>ohne INDEX schnell</strong>, doch je nachdem wie viele Einträge gespeichert könnte es sinnvoll sein einen Index zu erzeugen welche dann jedoch den Speicherverbrauch der Tabelle schlagartig verdoppelt. Jeder 124 KB Speicherblock hat anscheinend einen weiteren 124 KB Index Speicherblock wenn ein Index benutzt wird.</li>
</ul>
<ul>
<li> Was jedoch für die Nutzung von MEMORY spricht ist dass der Inhalt einer MEMORY Tabelle nur bei einem MySQL Server Neustart zwangsläufig geleert wird. Der APC Cache wird bei einem Webserver-Neustart geleert.</li>
</ul>
<h2>Nachtrag zu APC</h2>
<p>Zwar lassen meine Ausführungen die Nutzung von APC in einem nicht alzu guten Licht darstehen, doch dies spricht nicht gegen eine allgemeine Verwendung von APC da meine Tests sich nur auf das Speichern von Variablen beziehen. Als Opcode Cache ist es hervorragend und bietet dazu noch andere nützliche Funktionen.</p>
]]></content:encoded>
			<wfw:commentRss>http://juliusbeckmann.de/blog/php-apc-oder-mysql-memory-table-fuer-temporaeren-cache.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
