<?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>Es Tea Double Eye &#187; MySQL</title>
	<atom:link href="http://stii.co.za/tag/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://stii.co.za</link>
	<description>You&#039;re never too old for a happy childhood</description>
	<lastBuildDate>Fri, 19 Aug 2011 02:20:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<atom:link rel='hub' href='http://stii.co.za/?pushpress=hub'/>
		<item>
		<title>KohanaPHP and Memcached</title>
		<link>http://stii.co.za/php/kohanaphp-and-memcached/</link>
		<comments>http://stii.co.za/php/kohanaphp-and-memcached/#comments</comments>
		<pubDate>Mon, 25 May 2009 13:56:33 +0000</pubDate>
		<dc:creator>Stii</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[kohanaphp]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://stii.co.za/?p=675</guid>
		<description><![CDATA[This is shockingly simple&#8230; Almost so simple that I&#8217;m waiting for the problems, but after five days there has been none so far! When you develop a web application, at some point SQL query optimization just don&#8217;t cut it anymore. At Gatorpeeps, you will see we show each user&#8217;s latest blog post underneath each of [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://stii.co.za/wp-content/uploads/2009/01/picture-24.png" alt="Kohana PHP" title="Kohana PHP" width="358" height="142" class="alignright size-full wp-image-172" />This is shockingly simple&#8230; Almost so simple that I&#8217;m waiting for the problems, but after five days there has been none so far!</p>
<p>When you develop a web application, at some point SQL query optimization just don&#8217;t cut it anymore. At <a href="http://gatorpeeps.com">Gatorpeeps</a>, you will see we show each user&#8217;s latest blog post underneath each of his updates. The problem with this is that on any given page, we&#8217;ll run a query per update to get the user&#8217;s latest blog post. This is less than ideal, since it is repeating the same queries for every single visitor to a <strong>Gatorpeeps</strong> page.</p>
<p>What we want to do is to cache the repetitive query for a certain amount of time, so that instead of querying the database, it fetches it from the cache, dramatically <strong>reducing database load</strong> and improving speed.</p>
<p>With the <a href="http://stii.co.za/tag/kohanaphp">Kohana PHP framework</a> you have a number of options to your disposal namely:</p>
<ul>
<li>File &#8211; File cache is fast and reliable, but requires many filesystem lookups.</li>
<li>SQlite &#8211; Database cache can be used to cache items remotely, but is slower.</li>
<li>Memcache &#8211; Memcache is very high performance, but prevents cache tags from being used.</li>
<li>APC &#8211; Alternative Php Cache</li>
<li>Eaccelerator</li>
<li>Xcache</li>
</ul>
<p>We opted for <a href="http://www.danga.com/memcached/">Memcached</a> since it is fast, stable (so far at least!) and extremely simple to get going. We installed and configured it on our server (you should find lots of great guides for doing this if you search for it). We made sure the daemon is running then configured Kohana to use it. Very simple:</p>
<p>Open the <strong>cache.php</strong> file located in the <strong>system/config</strong> directory. Change it to:</p>
<pre>
$config['default'] = array
(
	'driver'   => 'memcache',
	'params'   => '',
	'lifetime' => 3600,
	'requests' => 1000
);
</pre>
<p>If you run <strong>Memcached</strong> on the same server as your PHP site, you can skip ahead and implement it. If you run it on a different server, you need to change the <strong>cache_memcache.php</strong> file also located in <strong>system/config</strong>. If you have more than one memcached server, you can add them to the $config['servers'] array.</p>
<pre>
$config['servers'] = array
(
	array
	(
		'host' => '127.0.0.1',
		'port' => 11211,
		'persistent' => FALSE,
	)
);

/**
 * Enable cache data compression.
 */
$config['compression'] = FALSE;
</pre>
<p>In your source code, you can now use the cache. We have a static function in a helper method to fetch the latest blog post of a user. We get a cache instance and we check if the entry exists in the cache. If it does, we return the result otherwise we add it to the cache with a lifetime of 10 minutes.</p>
<pre>
&lt;?php
... truncated ...
public static function getUserLatestBlogPost($user_id)
{
    $cache = Cache::instance();

    // Get the latest blog post from the cache by looking for an unique id like latest_post_123
    $post = $cache->get('latest_post_' . $user_id);
    if ($post) {
        // Found an entry in the cache. Return it.
        return $post;
    } else {
        // There is nothing in the cache for this user, so we need to fetch it from the database and
        // add it to the cache.
        $newpost = self::sqlUserLatestBlogPost($user_id);

        // Add it to the cache, changing the default lifetime from 1 hour (3600 seconds) to 10 minutes (600 seconds)
        $cache->set('latest_post_' . $user_id, $newpost, NULL, 600);
        return $newpost;
    }
}
... truncated ...
</pre>
<p>That&#8217;s it. It is really that simple! :) Now, you would probably want to write a method that deletes an old entry if a new entry is inserted into the database and reload the new blog post into the cache.</p>
<p><strong><em>REMEMBER</em></strong>: Use caching wisely! It is great, but as they say, too much of a good thing is bad. First make sure your SQL queries are properly optimized before you cache it. Make sure the data you cache is okay to be cached. What I mean by that is it would be senseless to cache data that is very dynamic and changes often. Caching everything WILL have an undesirable effect ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://stii.co.za/php/kohanaphp-and-memcached/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Installing Sphinx Search</title>
		<link>http://stii.co.za/mysql/installing-sphinx-search/</link>
		<comments>http://stii.co.za/mysql/installing-sphinx-search/#comments</comments>
		<pubDate>Mon, 17 Nov 2008 13:50:19 +0000</pubDate>
		<dc:creator>Stii</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Sphinx Search]]></category>
		<category><![CDATA[fulltext]]></category>
		<category><![CDATA[sphinxsearch]]></category>

		<guid isPermaLink="false">http://stii.co.za/?p=20</guid>
		<description><![CDATA[Now that you have been introduced to Sphinx Search, its time to set it up or install it. It is extremely simple. Just have a look at the guide for Debian, to give you an idea: sudo apt-get update sudo apt-get dist-upgrade sudo apt-get install build-essential sudo apt-get install libmysqlclient15-dev tar xvzf sphinx-0.9.8-rc2.tar.gz cd sphinx-0.9.8-rc2/ [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://sphinxsearch.com/g/sphinx.jpg" alt="Sphinx Search" style="float: right; margin: 5px;" />Now that you have been introduced to <a href="http://stii.co.za/mysql/sphinx-search-introduction/">Sphinx Search</a>, its time to set it up or install it. It is extremely simple. Just have a look at the guide for Debian, to give you an idea:</p>
<pre>
sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install build-essential
sudo apt-get install libmysqlclient15-dev

tar xvzf sphinx-0.9.8-rc2.tar.gz
cd sphinx-0.9.8-rc2/
./configure \
--with-mysql-includes=/usr/include/mysql \
--with-mysql-libs=/usr/lib/mysql
make
sudo make install
</pre>
<p>Below are two of the best guides I could find. One for installing on <strong>Debian</strong> and the other on <strong>CentOS</strong>.</p>
<ul>
<li><a href="http://www.my-whiteboard.com/linux-admin/install-and-configure-sphinx-search-engine-for-wordpress-on-centos-redhat.html">Install and configure Sphinx search engine for WordPress on CentOS RedHat | my-whiteboard</a></li>
<li><a href="http://www.urbanpuddle.com/articles/2008/06/29/install-sphinx-thinking-sphinx-in-debian">Urban Puddle : Install Sphinx &#038; Thinking Sphinx in Debian</a></li>
</ul>
<p>Next time, we&#8217;ll look at configuring it to actually work. Also, how to run some queries and how the results from Sphinx Search looks. </p>
]]></content:encoded>
			<wfw:commentRss>http://stii.co.za/mysql/installing-sphinx-search/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sphinx Search introduction</title>
		<link>http://stii.co.za/mysql/sphinx-search-introduction/</link>
		<comments>http://stii.co.za/mysql/sphinx-search-introduction/#comments</comments>
		<pubDate>Mon, 17 Nov 2008 08:24:36 +0000</pubDate>
		<dc:creator>Stii</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Sphinx Search]]></category>
		<category><![CDATA[fulltext]]></category>
		<category><![CDATA[sphinxsearch]]></category>

		<guid isPermaLink="false">http://stii.co.za/?p=8</guid>
		<description><![CDATA[Full text search is usually not a nicety, but often a necessity. To search a database text field by simply doing a normal SQL query could often result in a slow query, which is NOT GOOD. Now, you might not always have a need for full text search, specially if you have a smallish data [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://sphinxsearch.com/g/sphinx.jpg" alt="Sphinx Search" style="float: right; margin: 5px;" />Full text search is usually not a nicety, but often a necessity. To search a database text field by simply doing a normal SQL query could often result in a slow query, which is <strong>NOT GOOD</strong>. Now, you might not always have a need for full text search, specially if you have a smallish data set, but if you get to a certain threshold you&#8217;ll hit serious performance problems.</p>
<p>That is exactly what happened on <a href="http://afrigator.com">Afrigator</a>. We started out using normal, simple SQL SELECT queries. </p>
<pre>
SELECT * FROM posts
WHERE title LIKE '%keywords%'
OR body LIKE '%keywords%'
</pre>
<p>This was doing just great in the beginning. Nowadays our blog post table is close to a Gig in size and as you can imagine, that is a lot of words to try and filter to find specific terms! Funny thing is, a Gig is still tiny in web terms. What is a fact though is that it will only grow and with it, so would our performance issues!</p>
<p>Thank goodness for <strong><a href="http://sphinxsearch.com/">Sphinx Search</a></strong>! Sphinx Search is an open source (GPL2 License) full text search engine. It is FAST. Not only is search fast, but so also is the text indexing. </p>
<p>According to the Sphinx Search site, here is a list of features:</p>
<ul>
<li>high indexing speed (upto 10 MB/sec on modern CPUs);</li>
<li>high search speed (avg query is under 0.1 sec on 2-4 GB text collections);</li>
<li>high scalability (upto 100 GB of text, upto 100 M documents on a single CPU);</li>
<li>provides good relevance ranking through combination of phrase proximity ranking and statistical (BM25) ranking;</li>
<li>provides distributed searching capabilities;</li>
<li>provides document exceprts generation;</li>
<li>provides searching from within MySQL through pluggable storage engine;</li>
<li>supports boolean, phrase, and word proximity queries;</li>
<li>supports multiple full-text fields per document (upto 32 by default);</li>
<li>supports multiple additional attributes per document (ie. groups, timestamps, etc);</li>
<li>supports stopwords;</li>
<li>supports both single-byte encodings and UTF-8;</li>
<li>supports English stemming, Russian stemming, and Soundex for morphology;</li>
<li>supports MySQL natively (MyISAM and InnoDB tables are both supported);</li>
<li>supports PostgreSQL natively.</li>
</ul>
<p>As you can see, that&#8217;s quite a nifty feature set! When we implemented it on Afrigator, we chose to run Sphinx Search as a daemon, though you could compile MySQL with Sphinx support should you choose.</p>
<p>It was also <strong>SUPER SIMPLE</strong> to set it up! All you would have to have to get it running for your own application is to be able to compile C++ on your web server. I.e. you&#8217;d have to have a shell account and capabilities to compile using gcc on Linux.</p>
<p>One tiny hiccup I experienced was that I needed to have the libmysqlclient-dev package installed (if you haven&#8217;t already) in order for Sphinx to compile. They don&#8217;t mention that in the documentation, so just be aware of that. Other than that, you simply have to follow the steps in the documentation to get it up and running.</p>
<p>Once compiled successfully, you have to set it up and configure it. More on that at a later stage. For now, if you are developing web apps that is heavily dependent on full text search, I can recommend Sphinx Search as a viable solution.</p>
]]></content:encoded>
			<wfw:commentRss>http://stii.co.za/mysql/sphinx-search-introduction/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

