<?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>Kerkness.ca &#187; mysql</title>
	<atom:link href="http://www.kerkness.ca/tagged/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kerkness.ca</link>
	<description>flexing my kerkness, among other things</description>
	<lastBuildDate>Wed, 14 Oct 2009 15:12:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.3</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Getting a performance boost from MySQL</title>
		<link>http://www.kerkness.ca/getting-a-performance-boost-from-mysql/</link>
		<comments>http://www.kerkness.ca/getting-a-performance-boost-from-mysql/#comments</comments>
		<pubDate>Sat, 26 Apr 2008 01:07:00 +0000</pubDate>
		<dc:creator>Kerk</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.kerkness.ca/blog/?p=41</guid>
		<description><![CDATA[I have to admit I am no database guru but I do know how to organize my information into a decent set of tables. Every table has a primary key and every field is just large enough and the right type for the data it needs to hold. In general my databases always perform well [...]]]></description>
			<content:encoded><![CDATA[<p>I have to admit I am no database guru but I do know how to organize my information into a decent set of tables. Every table has a <span style="font-style: italic;">primary key</span> and every field is just large enough and the right type for the data it needs to hold. In general my databases always perform well (enough) and I have little issue.</p>
<p>Then while reading up on how to properly configure replication with MySQL I stumbled upon some information on <span style="font-style: italic;">Indexes</span> and I realized that I wasn&#8217;t using my database as best I could.</p>
<p>If you asked me a week ago what an <span style="font-style: italic;">&#8216;Index&#8217;</span> was in relation to a MySQL table I would have told you it was the <span style="font-style: italic;">&#8216;primary key&#8217;</span>.  Which is only partially true. While the <span style="font-style: italic;">primary key</span> is automatically used as an <span style="font-style: italic;">Index</span> for a table it doesn&#8217;t have to be the only <span style="font-style: italic;">Index</span> for the table.</p>
<p><span style="font-weight: bold;">What is an Index</span></p>
<p>An <span style="font-style: italic;">Index</span> is basically a method MySQL (and other databases) use to organize a table to make it easier to search. For example,  because the <span style="font-style: italic;">primary key</span> for any table is indexed (and unique) when you search the table for a record matching a <span style="font-style: italic;">primary key</span> value, the database knows it only needs to find 1 matching record. If there was no <span style="font-style: italic;">primary key</span> the database doesn&#8217;t know how many possible matches it needs to find so it will have to look at every single record to try and find all possible matches.</p>
<p>Knowing this, if you create <span style="font-style: italic;">Indexes</span> for your table on all fields which are frequently searched or are used in <span style="font-style: italic;">Join</span> statements you&#8217;ll help your database find records more easily.</p>
<p><span style="font-weight: bold;">An Example</span></p>
<p>I typically use a lot of joins when I query the database. Let&#8217;s look at how one of these join queries perform without any <span style="font-style: italic;">Indexing</span> ( apart from the default indexing of my <span style="font-style: italic;">primary keys</span> ).</p>
<p>In my database there is a table called &#8216;artist&#8217; which contains the names, biography and details on different artists. The artist table has a <span style="font-style: italic;">primary key</span> field call artistid. In the same database there is another table called artwork which contains details on individual pieces of art.  The artwork table has a <span style="font-style: italic;">primary key</span> field called artid, but it also contains its own artistid field. The artist and artwork tables have a one-to-many relationship, meaning that a single artist can have many works of art.</p>
<p>Using this database design, you can load a complete listing of works of art by a single artist with the following query.
<pre>SELECT artwork.*, artist.* FROM artwork LEFT JOIN artist ON artwork.artistid=artist.artistid WHERE artwork.artistid=46;</pre>
<p>This query will work just fine. However if we want to gain some insight into how much information MySQL needs to process to perform this query we can add the EXPLAIN declaration to the front of the query.
<pre>EXPLAIN SELECT artwork.*, artist.* FROM artwork LEFT JOIN artist ON artwork.artistid=artist.artistid WHERE artwork.artistid=46;</pre>
<p>When we run this query at the command prompt MySQL gives the following response.
<pre>+----+-------------+---------+-------+---------------+----------+---------+-------+------+-------------+| id | select_type | table   | type  | possible_keys | key      | key_len | ref   | rows | Extra       |+----+-------------+---------+-------+---------------+----------+---------+-------+------+-------------+|  1 | SIMPLE      | artwork | ALL   | NULL          | NULL     | NULL    | NULL  | 3106 | Using where ||  1 | SIMPLE      | artist  | const | artistid      | artistid | 4       | const |    1 |             |+----+-------------+---------+-------+---------------+----------+---------+-------+------+-------------+</pre>
<p>This tells us that when looking up information from the artist table the database was able to use the <span style="font-style: italic;">primary key</span> index and looked at a total of 1 rows in the table in order to find the information it needed. That seems pretty efficient. However when looking in the artwork table the database had do a full table scan and looked at 3106 rows to find matching records.</p>
<p>Let&#8217;s see what happens when we add an <span style="font-style: italic;">Index</span> on artistid to the artwork table.
<pre>ALTER TABLE artwork ADD INDEX( artistid );</pre>
<p>Now when we run the same EXPLAIN query we get the following details from MySQL
<pre>+----+-------------+---------+-------+---------------+----------+---------+-------+------+-------------+| id | select_type | table   | type  | possible_keys | key      | key_len | ref   | rows | Extra       |+----+-------------+---------+-------+---------------+----------+---------+-------+------+-------------+|  1 | SIMPLE      | artwork | ref   | artistid      | artistid | 5       | const |    4 | Using where ||  1 | SIMPLE      | artist  | const | artistid      | artistid | 4       | const |    1 |             |+----+-------------+---------+-------+---------------+----------+---------+-------+------+-------------+</pre>
<p>Now doesn&#8217;t that look much more efficient.  This time because the database is keeping an <span style="font-style: italic;">Index</span> on the artistid field in both tables.  It only needed to look at 4 rows from the artwork table to find the matching results.</p>
<p>I did some additional performance testing to see how much of a boost adding this one extra <span style="font-style: italic;">Index</span> provided during peak times of database use.  Prior to the indexing the query on average took 0.06 seconds, after the indexing it took 0.00. That&#8217;s just on one tiny little query on a database that has only 3000 records. If you start adding extra indexes to all the tables in your database you should notice a nice boost in speed and performance.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerkness.ca/getting-a-performance-boost-from-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
