<?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>TheUnical Technologies Blog &#187; Query</title>
	<atom:link href="http://blog.theunical.com/category/databases/query/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.theunical.com</link>
	<description>TheUnical Technologies Official Blog</description>
	<lastBuildDate>Fri, 27 Jan 2012 05:48:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Three easy ways to optimize your MySQL queries</title>
		<link>http://blog.theunical.com/databases/mysql/three-easy-ways-to-optimize-your-mysql-queries/</link>
		<comments>http://blog.theunical.com/databases/mysql/three-easy-ways-to-optimize-your-mysql-queries/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 05:32:00 +0000</pubDate>
		<dc:creator>Steven Wall</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[MySQL 5.1]]></category>
		<category><![CDATA[MySql]]></category>
		<category><![CDATA[MySql 5.0]]></category>
		<category><![CDATA[Query]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[MySql5.1]]></category>
		<category><![CDATA[Sql Optimization]]></category>

		<guid isPermaLink="false">http://rachasatish.wordpress.com/2008/12/15/three-easy-ways-to-optimize-your-mysql-queries/</guid>
		<description><![CDATA[Any database programmer will tell you that in high-traffic database-driven applications, a single badly-designed SQL query can significantly impact the overall performance of your application. Not only does such a query consume more database time than it ideally should, but it can have an exponential effect on the performance of other application components. Optimizing query [...]]]></description>
			<content:encoded><![CDATA[<div class="Section1">
<p class="MsoNormal"><span style="font-family:Calibri;font-size:85%;"><span style="font-size:11px;"> </span></span></p>
<p><span style="font-family:Times New Roman;font-size:100%;"><span style="font-size:12px;">Any database programmer will tell you that in high-traffic database-driven applications, a single badly-designed <a href="http://search.techrepublic.com.com/index.php?c=1&amp;q=sql+optimization" target="_blank">SQL query</a> can significantly impact the overall performance of your application. Not only does such a query consume more database time than it ideally should, but it can have an exponential effect on the performance of other application components. </span></span></p>
<p><span style="font-family:Times New Roman;font-size:100%;"><span style="font-size:12px;">Optimizing query performance is as much a black art as a science, as heavily dependent on the developer&#8217;s intuition as on hard statistical performance data. Fortunately, databases likes <a href="http://search.techrepublic.com.com/index.php?c=1&amp;q=mysql&amp;t=11" target="_blank">MySQL</a> come with some tools to aid the process, and this article discusses three of them briefly: using indexes, analyzing queries with <i><span style="font-style:italic;">EXPLAIN</span></i>, and adjusting MySQL&#8217;s internal configuration. </span></span></p>
<h2><b><span style="font-family:Times New Roman;font-size:180%;"><span style="font-size:18px;">#1: Using indexes</span></span></b></h2>
<p><span style="font-family:Times New Roman;font-size:100%;"><span style="font-size:12px;">MySQL allows you to index database tables, making it possible to quickly seek to records without performing a full table scan first and thus significantly speeding up query execution. You can have up to 16 indexes per table, and MySQL also supports multi-column indexes and full-text search indexes. </span></span></p>
<p><span style="font-family:Times New Roman;font-size:100%;"><span style="font-size:12px;">Adding an index to a table is as simple as calling the <i><span style="font-style:italic;">CREATE INDEX</span></i> command and specifying the field(s) to index. <b><span style="font-weight:bold;">Listing A</span></b> shows you an example:</span></span></p>
<h3><b><span style="font-family:Times New Roman;font-size:130%;"><span style="font-size:13px;">Listing A</span></span></b></h3>
<p class="MsoNormal"><span style="font-family:Calibri;font-size:85%;"><span style="font-size:11px;"><br /><span class="code">mysql&gt; CREATE INDEX idx_username ON users(username);</span><br /><span class="code">Query OK, 1 row affected (0.15 sec)</span><br /><span class="code">Records: 1  Duplicates: 0  Warnings: 0</span> </span></span></p>
<p><span style="font-family:Times New Roman;font-size:100%;"><span style="font-size:12px;">Here, indexing the <i><span style="font-style:italic;">username</span></i> field of the <i><span style="font-style:italic;">users</span></i> table ensures that <i><span style="font-style:italic;">SELECT</span></i> queries which reference this field in their <i><span style="font-style:italic;">WHERE</span></i> or <i><span style="font-style:italic;">HAVING</span></i> clause will run a little faster than in the pre-indexed state. You can check that the index was created (<b><span style="font-weight:bold;">Listing B</span></b>) with the <i><span style="font-style:italic;">SHOW INDEX</span></i> command:</span></span></p>
<h3><b><span style="font-family:Times New Roman;font-size:130%;"><span style="font-size:13px;">Listing B</span></span></b></h3>
<p class="MsoNormal"><span style="font-family:Calibri;font-size:85%;"><span style="font-size:11px;"><br /><span class="code">mysql&gt; SHOW INDEX FROM users;</span><br /><span class="code">&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8211;+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;+</span><br /><span class="code">| Table | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |</span><br /><span class="code">&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8211;+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;+</span><br /><span class="code">| users |          1 | idx_username |            1 | username    | A         |      NULL |     NULL | NULL   | YES  | BTREE      |         |</span><br /><span class="code">&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8211;+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;+</span><br /><span class="code">1 row in set (0.00 sec)</span> </span></span></p>
<p><span style="font-family:Times New Roman;font-size:100%;"><span style="font-size:12px;">It&#8217;s important to note that indexes are a double-edged sword. Indexing every field of a table is usually unnecessary, and is quite likely to slow things down significantly when inserting or updating data because of the additional work MySQL has to do to rebuild the index each time. On the other hand, avoiding indexes altogether isn&#8217;t such a great idea either, because while this will speed up <i><span style="font-style:italic;">INSERTs</span></i>, it will cause <i><span style="font-style:italic;">SELECT</span></i> operations to slow down. There is thus always a trade-off to be made, and it&#8217;s wise to consider what the primary function of the table will be (data retrieval or data edit) when designing the indexing system.</span></span></p>
<h2><b><span style="font-family:Times New Roman;font-size:180%;"><span style="font-size:18px;">#2: Optimizing query performance</span></span></b></h2>
<p><span style="font-family:Times New Roman;font-size:100%;"><span style="font-size:12px;">When analyzing query performance, it&#8217;s also useful to consider the <i><span style="font-style:italic;">EXPLAIN</span></i> keyword. This keyword, when placed in front of a <i><span style="font-style:italic;">SELECT</span></i> query, describes how MySQL intends to execute the query and the number of rows it will need to process to successfully deliver a result set. To illustrate, consider the following simple example (<b><span style="font-weight:bold;">Listing C</span></b>):</span></span></p>
<h3><b><span style="font-family:Times New Roman;font-size:130%;"><span style="font-size:13px;">Listing C</span></span></b></h3>
<p class="MsoNormal"><span style="font-family:Calibri;font-size:85%;"><span style="font-size:11px;"><br /><span class="code">mysql&gt; EXPLAIN SELECT city.name, city.district FROM city, country WHERE city.countrycode = country.code AND country.code = &#8216;IND&#8217;;</span><br /><span class="code">+&#8212;-+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;-+</span><br /><span class="code">| id | select_type | table   | type  | possible_keys | key     | key_len | ref  | rows | Extra       |</span><br /><span class="code">+&#8212;-+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;-+</span><br /><span class="code">|  1 | SIMPLE      | country | const | PRIMARY       | PRIMARY | 3       | const |    1 | Using index |</span><br /><span class="code">|  1 | SIMPLE      | city    | ALL   | NULL          | NULL    | NULL    | NULL | 4079 | Using where |</span><br /><span class="code">+&#8212;-+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;-+</span><br /><span class="code">2 rows in set (0.00 sec)</span> </span></span></p>
<p><span style="font-family:Times New Roman;font-size:100%;"><span style="font-size:12px;">Here, the query is structured as a join between two tables and the <i><span style="font-style:italic;">EXPLAIN</span></i> keyword describes how MySQL will process the join. It should be clear the current design will require MySQL to process only one record in the <i><span style="font-style:italic;">country</span></i> table (which is indexed) but all 4079 records in the <i><span style="font-style:italic;">city</span></i> table (which isn&#8217;t). This then suggests scope for improvement using other optimization tricks &#8211; for example, adding an index to the <i><span style="font-style:italic;">city</span></i> table as follows (<b><span style="font-weigh</p>
<p>t:bold;">Listing D</span></b>):</span></span></p>
<h3><b><span style="font-family:Times New Roman;font-size:130%;"><span style="font-size:13px;">Listing D</span></span></b></h3>
<p class="MsoNormal"><span style="font-family:Calibri;font-size:85%;"><span style="font-size:11px;"><br /><span class="code">mysql&gt; <b><span style="font-weight:bold;">CREATE INDEX idx_ccode ON city(countrycode);</span></b></span><b><span style="font-weight:bold;"><br /></span></b><span class="code">Query OK, 4079 rows affected (0.15 sec)</span><br /><span class="code">Records: 4079  Duplicates: 0  Warnings: 0</span> </span></span></p>
<p><span style="font-family:Times New Roman;font-size:100%;"><span style="font-size:12px;">And now, when you re-run the query with <i><span style="font-style:italic;">EXPLAIN</span></i>, you&#8217;ll see a noticeable improvement (<b><span style="font-weight:bold;">Listing E</span></b>):</span></span></p>
<h3><b><span style="font-family:Times New Roman;font-size:130%;"><span style="font-size:13px;">Listing E</span></span></b></h3>
<p class="MsoNormal"><span style="font-family:Calibri;font-size:85%;"><span style="font-size:11px;"><br /><span class="code">mysql&gt; EXPLAIN SELECT city.name, city.district FROM city, country WHERE city.countrycode = country.code AND country.code = &#8216;IND&#8217;;</span><br /><span class="code">+&#8212;-+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;-+</span><br /><span class="code">| id | select_type | table   | type  | possible_keys | key       | key_len | ref   | rows | Extra       |</span><br /><span class="code">+&#8212;-+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;-+</span><br /><span class="code">|  1 | SIMPLE      | country | const | PRIMARY       | PRIMARY   | 3       | const |    1 | Using index |</span><br /><span class="code">|  1 | SIMPLE      | city    | ref   | idx_ccode     | idx_ccode | 3       | const |  333 | Using where |</span><br /><span class="code">+&#8212;-+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;-+</span><br /><span class="code">2 rows in set (0.01 sec)</span> </span></span></p>
<p><span style="font-family:Times New Roman;font-size:100%;"><span style="font-size:12px;">As this illustrates, MySQL now only needs to scan 333 records in the <i><span style="font-style:italic;">city</span></i> table to produce a result set &#8212; a reduction of almost 90 percent! Naturally, this translates into faster query execution time and more efficient usage of database resources.</span></span></p>
<h2><b><span style="font-family:Times New Roman;font-size:180%;"><span style="font-size:18px;">#3: Adjusting internal variables</span></span></b></h2>
<p><span style="font-family:Times New Roman;font-size:100%;"><span style="font-size:12px;">MySQL is so open that it&#8217;s fairly easy to further fine-tune its default settings to obtain greater performance and stability. Some of the key variables that should be optimized are listed below.</span></span></p>
<ul type="disc">
<li class="MsoNormal"><b><span style="font-family:Calibri;font-size:85%;"><span style="font-weight:bold;font-size:11px;">Altering Index Buffer Size      (key_buffer)<br />     </span></span></b>This variable controls the size of the buffer used when      handling table indices (both read and write operations). The MySQL manual      recommends that this variable be increased &#8220;to as much as you can      afford&#8221; to ensure you get the best performance on indexed tables, and      recommends a value equivalent to about 25 percent of the total system memory.      This is one of the more important MySQL configuration variables and if      you&#8217;re interested in optimizing and improving performance, trying      different values for the <i><span style="font-style:italic;">key_buffer_size</span></i>      variable is a good place to start.</li>
<li class="MsoNormal"><b><span style="font-family:Calibri;font-size:85%;"><span style="font-weight:bold;font-size:11px;">Altering Table Buffer Size      (read_buffer_size)<br />     </span></span></b>When a query requires a table to be scanned      sequentially, MySQL allocates a memory buffer to this query. The <i><span style="font-style:italic;">read_buffer_size</span></i> variable controls      the size of this buffer. If you find that sequential scans are proceeding      slowly, you can improve performance by increasing this value, and hence      the size of the memory buffer.</li>
<li class="MsoNormal"><b><span style="font-family:Calibri;font-size:85%;"><span style="font-weight:bold;font-size:11px;">Setting The Number Of Maximum      Open Tables (table_cache)<br />     </span></span></b>This variable controls the maximum number of tables      MySQL can have open at any one time, and thus controls the server&#8217;s      ability to respond to incoming requests. This variable is closely related      to the <i><span style="font-style:italic;">max_connections</span></i>      variables &#8212; increasing this value allows MySQL to keep a larger number of      tables open, just as increasing <i><span style="font-style:italic;">max_connections</span></i>      increases the number of allowed connections. Consider altering this value      if you have a high-volume server which receives queries on multiple      different databases and tables.</li>
<li class="MsoNormal"><b><span style="font-family:Calibri;font-size:85%;"><span style="font-weight:bold;font-size:11px;">Deciding A Time Limit For Long      Queries (long_query_time)<br />     </span></span></b>MySQL comes with a so-called &#8220;slow query log&#8221;,      which automatically logs all queries that do not end within a particular      time limit. This log is useful to track inefficient or misbehaving      queries, and to find targets for optimization algorithms. The <i><span style="font-style:italic;">long_query_time</span></i> variable controls this      maximum time limit, in seconds.</li>
</ul>
<p><span style="font-family:Times New Roman;font-size:100%;"><span style="font-size:12px;">The previous discussion should give you some insight into three tools you can use to analyze and optimize your SQL queries, and help you squeeze better performance out of your application. Go on and try them out &#8212; and happy optimizing!</span></span></p>
<p class="MsoNormal"><span style="font-family:Calibri;font-size:85%;"><span style="font-size:11px;"> </span></span></p>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.theunical.com/databases/mysql/three-easy-ways-to-optimize-your-mysql-queries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

