<?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>PoundBangWhack.com</title>
	<atom:link href="http://www.poundbangwhack.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.poundbangwhack.com</link>
	<description>A web development/programming blog providing info, tips, and tricks on programming languages, scripting, Linux, MySQL and more</description>
	<lastBuildDate>Wed, 17 Feb 2010 17:23:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Our first WordPress Plugin: WordPress Woot Watcher</title>
		<link>http://www.poundbangwhack.com/2010/02/17/our-first-wordpress-plugin-wordpress-woot-watcher/</link>
		<comments>http://www.poundbangwhack.com/2010/02/17/our-first-wordpress-plugin-wordpress-woot-watcher/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 17:23:29 +0000</pubDate>
		<dc:creator>Mark Stoecker</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Wordpress Plugins]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[Woot]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.poundbangwhack.com/?p=1268</guid>
		<description><![CDATA[In conjunction with Lee Thompson of MySQLHow2.com, we have released our first WordPress Plugin: 
WordPress Woot Watcher

WordPress Woot Watcher, will monitor and check woot, shirt.woot, kids.woot, wine.woot and sellout.woot for new products every 10 hours. When a woot-off is launched, the widget will update the woot product every 30 seconds. WordPress Woot Watcher is a [...]]]></description>
			<content:encoded><![CDATA[<p>In conjunction with <a href="http://www.mysqlhow2.com">Lee Thompson of MySQLHow2.com</a>, we have released our first WordPress Plugin: </p>
<blockquote><h4><a href="http://www.poundbangwhack.com/wordpress/plugins/wordpress-woot-watcher/">WordPress Woot Watcher</a></h4>
</blockquote>
<p>WordPress Woot Watcher, will monitor and check woot, shirt.woot, kids.woot, wine.woot and sellout.woot for new products every 10 hours. When a woot-off is launched, the widget will update the woot product every 30 seconds. WordPress Woot Watcher is a sidebar widget that enables select the woot sites you want to monitor in the administration section. The default installation selects woot.com only.</p>
<p>For all the details, installation, and more, visit the <a href="http://www.poundbangwhack.com/wordpress/plugins/wordpress-woot-watcher/">WordPress Woot Watcher</a> page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poundbangwhack.com/2010/02/17/our-first-wordpress-plugin-wordpress-woot-watcher/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to append values to an array in bash</title>
		<link>http://www.poundbangwhack.com/2010/02/04/how-to-append-values-to-an-array-in-bash/</link>
		<comments>http://www.poundbangwhack.com/2010/02/04/how-to-append-values-to-an-array-in-bash/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 20:14:08 +0000</pubDate>
		<dc:creator>Mark Stoecker</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[SSH/Command Line]]></category>
		<category><![CDATA[Shell Scripts]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SSH]]></category>

		<guid isPermaLink="false">http://www.poundbangwhack.com/?p=1257</guid>
		<description><![CDATA[Last week I was working on a bash script for a project at work.  The script parsed through a log file with server load and disk usage statistics at regular intervals.  The script was calculating the average CPU idle time, disk utilization, and disk usage for servers.  After calculating the averages for [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I was working on a bash script for a project at work.  The script parsed through a log file with server load and disk usage statistics at regular intervals.  The script was calculating the average CPU idle time, disk utilization, and disk usage for servers.  After calculating the averages for each of these three metrics, I then proceeded to loop through all the lines in the file and create an array of all the times when the CPU idle time was below average, or the disk utilization or usage was above average.<br />
<span id="more-1257"></span><br />
The code that I used was originally taken from the article <a href="http://fvue.nl/wiki/Bash:_Append_to_array_using_while-loop" target="_blank">Bash: Append to array using while-loop</a> by Freddy Vulto. The concept that Freddy used is essentially the same as what I was doing.  I was using a <span class="pre">for</span> loop to scan a file, and if certain values in the file met a condition, the date was added to an array which was printed at the end of the script execution.  The code to achieve this is as follows:</p>
<p><code>array=( ${array[@]-} $(echo "$variable") )</code></p>
<p>The code above reads as follows:</p>
<p><span class="pre">array=( &#8230;.. )</span> : Set your array variable named, appropriately enough: <em>array</em>.</p>
<p><span class="pre">${array[@]-}</span> : Read all variables from the array <em>array</em>.  The hyphen at the end prevents an &#8220;unbound variable&#8221; error when <span class="code">-u</span> or <span class="code">-o nounset</span> is set and <em>array</em> is an empty array.  This is useful for appending the first value to an empty array in the event that one of the aforementioned flags is set.</p>
<p><span class="pre">$(echo &#8220;$variable&#8221;)</span> : Add the variable <em>$variable</em> to the array through the use of command substitution <span class="code">$(&#8230;)</span> by reading the output of <span class="code">echo &#8220;$variable&#8221;</span> as the input value for the array.  The reason for command substitution is that if you try it without the <span class="code">$(&#8230;)</span>, bash will read <span class="code">echo</span> and <span class="code">&#8220;$variable&#8221;</span> as separate entries into the array instead of just the value of <em>$variable</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.poundbangwhack.com/2010/02/04/how-to-append-values-to-an-array-in-bash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improve Your WordPress Blog&#8217;s Performance With this Database Hack</title>
		<link>http://www.poundbangwhack.com/2010/01/09/improve-your-wordpress-blogs-performance-with-this-database-hack/</link>
		<comments>http://www.poundbangwhack.com/2010/01/09/improve-your-wordpress-blogs-performance-with-this-database-hack/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 05:52:50 +0000</pubDate>
		<dc:creator>Mark Stoecker</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Hack]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.poundbangwhack.com/?p=1236</guid>
		<description><![CDATA[One of daily responsibilities as a database administrator is maintaining the health of our shared hosting environment.  In doing so, I deal with plenty of <a href="http://www.wordpress.org">WordPress</a> blogs daily.  The one thing I have noticed is that <a href="http://www.poundbangwhack.com/2009/12/02/avoid-wordpress-statpress-plugin-like-the-plague/">many WordPress plugins are very poorly designed and can cause problems</a> in a shared hosting environment.  WordPress at it's core though, is very well designed, although I have noticed some areas of possible improvement.  As I come across common issues, I will post the fixes for them here for all to use.]]></description>
			<content:encoded><![CDATA[<p><em><strong>**UPDATE**:</strong> After further research of the query below, I have found some additional information.  The query was first introduced in WP 2.3 and is used for comment flood protection.  I am currently running WP 2.9.1 and do not have the issue as the query has been modified and using a proper index to assist with the query speed.  If you are using the latest version of WP, you won&#8217;t have this problem.  I am still trying to find exactly when the query was changed so you all can know where you stand.  However, I know that some people don&#8217;t upgrade their WP version due to changes they have made which upgrading will break.  If you are on an older version of WP and have a large number of comments (tens to hundreds of thousands), this query will help improve your comment post times.  If you are familiar enough with MySQL, look at the wp_comments table in your database.  If there is an index on the `comment_date_gmt` column, you are ok.  If not, read on, and run the query below as adding an index to the `comment_date_gmt` column won&#8217;t work as your query does not have that column in it&#8217;s WHERE clause.</em></p>
<p>One of daily responsibilities as a database administrator is maintaining the health of our shared hosting environment.  In doing so, I deal with plenty of <a href="http://www.wordpress.org">WordPress</a> blogs daily.  The one thing I have noticed is that <a href="http://www.poundbangwhack.com/2009/12/02/avoid-wordpress-statpress-plugin-like-the-plague/">many WordPress plugins are very poorly designed and can cause problems</a> in a shared hosting environment.  WordPress at it&#8217;s core though, is very well designed, although I have noticed some areas of possible improvement.  As I come across common issues, I will post the fixes for them here for all to use.<br />
<span id="more-1236"></span><br />
The following is one of the most common queries I see all the time that actually comes from the WordPress core:<br />
<code>SELECT comment_date_gmt<br />
FROM wp_comments<br />
WHERE comment_author_IP = '94.142.131.22' OR<br />
	comment_author_email = 'yigrzds@tkgmd.com'<br />
ORDER BY comment_date DESC<br />
LIMIT 1<br />
</code></p>
<p>The IP and email is obviously only sample data.  On the example server, the <a href="http://dev.mysql.com/doc/refman/5.0/en/using-explain.html">MySQL Explain</a> for the query showed the following:</p>
<p><code>id: 1<br />
select_type: SIMPLE<br />
table: wp_comments<br />
type: ALL<br />
possible_keys: NULL<br />
key: NULL<br />
key_len: NULL<br />
ref: NULL<br />
rows: 76845<br />
Extra: Using where; Using filesort</code></p>
<p>Now, a query that examines 76,000+ rows is not the end of the world, but with enough traffic, it can slow down the server immensely, mainly because the explain above indicates that no key is being used on the query and therefore a full table scan is being performed.</p>
<p>To help alleviate this, the following code can be executed from a MySQL command prompt, or a management type interface like phpMyAdmin:</p>
<p><code>mysql> <strong>ALTER TABLE wp_comments ADD INDEX(comment_author_IP), ADD INDEX(comment_author_email)</strong></code></p>
<p><strong>**Note: The above optimization assumes the default database prefix of &#8220;wp&#8221;.  If your database prefix is different, replace &#8220;wp&#8221; in the above query with your databases prefix.**</strong></p>
<p>Afterward, the explain on the exact same query returns the following:</p>
<p><code>id: 1<br />
select_type: SIMPLE<br />
table: wp_comments<br />
type: index_merge<br />
possible_keys: comment_author_IP,comment_author_email<br />
key: comment_author_IP,comment_author_email<br />
key_len: 302,302<br />
ref: NULL<br />
rows: 2139<br />
Extra: Using union(comment_author_IP,comment_author_email); Using where; Using filesort</code></p>
<p>As you can see, the query now examines 2139 rows as opposed to 76,000+ by using an <a href="http://dev.mysql.com/doc/refman/5.0/en/index-merge-optimization.html">Index Merge,</a> which means the query is pulling data using two different indexes on the same query.  Now keep in mind, index merges are only available in MySQL 5.0+.  If you are using MySQL 4.1 or below, an index merge will not work, and I would suggest adding an index on the comment_author_IP field as it will tend to have more unique values.  Simply remove everything after the comma in the above command.  </p>
<p>This optimization will improve the speed of the query on your database and will provide better performance on your WordPress blog.  Please share your thoughts below on this hack and the results for you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poundbangwhack.com/2010/01/09/improve-your-wordpress-blogs-performance-with-this-database-hack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What does &#8220;Impossible WHERE noticed after reading const tables&#8221; mean?</title>
		<link>http://www.poundbangwhack.com/2009/12/09/what-does-impossible-where-noticed-after-reading-const-tables-mean/</link>
		<comments>http://www.poundbangwhack.com/2009/12/09/what-does-impossible-where-noticed-after-reading-const-tables-mean/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 19:34:36 +0000</pubDate>
		<dc:creator>Mark Stoecker</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Query Optimization]]></category>

		<guid isPermaLink="false">http://www.poundbangwhack.com/?p=1056</guid>
		<description><![CDATA[When it comes to <em>basic</em> query optimization and analysis, in my opinion, there is no better tool than the <a href="http://dev.mysql.com/doc/refman/5.0/en/explain.html" target="_blank">MySQL EXPLAIN command</a>.  It can prove to be an invaluable to for deciphering the MySQL query execution plan, or the way that MySQL is optimizing and executing the query.  It will show you the type of SELECT being made on the table, the join type, possible keys, used keys, rows analyzed and more.  ]]></description>
			<content:encoded><![CDATA[<p>When it comes to <em>basic</em> query optimization and analysis, in my opinion, there is no better tool than the <a href="http://dev.mysql.com/doc/refman/5.0/en/explain.html" target="_blank">MySQL EXPLAIN command</a>.  It can prove to be an invaluable tool for deciphering the MySQL query execution plan, or the way that MySQL is optimizing and executing the query.  It will show you the type of SELECT being made on the table, the join type, possible keys, used keys, rows analyzed and more.  I won&#8217;t get into the nitty gritty of EXPLAIN in this post, but if you are using it, on occasion you may get the following output:</p>
<pre class="code">+-----------------------------------------------------+
| Extra                                               |
+-----------------------------------------------------+
| Impossible WHERE noticed after reading const tables |
+-----------------------------------------------------+</pre>
<p><span id="more-1056"></span><br />
There are two things to know in order to decipher this.  First off, what is a &#8220;const table&#8221;.  The &#8220;type&#8221; column refers to the join type made on the tables.  The &#8220;const&#8221; type is the bets type of join type you can make, after a &#8220;system&#8221; type, which is a special case of the &#8220;const&#8221; join type when the table has only 1 row in it.  According to the MySQL manual:</p>
<blockquote><p>The table has at most one matching row, which is read at the start of the query. Because there is only one row, values from the column in this row can be regarded as constants by the rest of the optimizer. const tables are very fast because they are read only once.</p>
<p><em style="font-size: smaller;">(source: <a href="http://dev.mysql.com/doc/refman/5.0/en/using-explain.html#jointype_const" target="_blank">MySQL ::   MySQL 5.0 Reference Manual :: 7.2.1 Optimizing Queries with EXPLAIN</a>)</em></p></blockquote>
<p>A &#8220;const&#8221; join type occurs when you run a very specific WHERE clause in your query that matches at most, one row from the referenced table.  </p>
<p>The second thing to know is the &#8220;Impossible WHERE noticed&#8221;.  This does not mean that your WHERE clause is wrong, it simple means &#8220;MySQL has read all const (and system) tables and notice that the WHERE clause is always false&#8221; <em style="font-size: smaller;">(source: <a href="http://dev.mysql.com/doc/refman/5.0/en/using-explain.html" target="_blank">MySQL ::   MySQL 5.0 Reference Manual :: 7.2.1 Optimizing Queries with EXPLAIN</a>)</em>.</p>
<p>So in summation, the statement <b>&#8220;Impossible WHERE noticed after reading const tables&#8221; simply means, that your query returned an empty result set (0 rows).</b>  You won&#8217;t always get this error on an EXPLAIN command when 0 rows are returned, but when you do get it, that&#8217;s what it means.  I hope this helps</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poundbangwhack.com/2009/12/09/what-does-impossible-where-noticed-after-reading-const-tables-mean/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Check out Google&#8217;s new search interface and try it for yourself</title>
		<link>http://www.poundbangwhack.com/2009/12/07/check-out-googles-new-interface-and-try-it-for-yourself/</link>
		<comments>http://www.poundbangwhack.com/2009/12/07/check-out-googles-new-interface-and-try-it-for-yourself/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 04:30:32 +0000</pubDate>
		<dc:creator>Mark Stoecker</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Search Engines]]></category>

		<guid isPermaLink="false">http://www.poundbangwhack.com/?p=1045</guid>
		<description><![CDATA[I came across a post the other day about a new Google Interface in development and tried it out for myself.  I have to say, it&#8217;s not bad.  If you look at the screenshots below, you&#8217;ll see that the home page is using a bit brighter colors, as well as some subtle gradients, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://felipeferreira.net/?p=672">I came across a post the other day</a> about a <a href="http://www.dailyseoblog.com/2009/11/try-the-new-google-interface-if-you-havent-yet/">new Google Interface in development</a> and tried it out for myself.  I have to say, it&#8217;s not bad.  If you look at the screenshots below, you&#8217;ll see that the home page is using a bit brighter colors, as well as some subtle gradients, and the colorizing of the input buttons instead of the standard gray.  The differences on the search results page are obvious.  Again, the colors and gradients, as well as a strong font in the search box and additional search options on the left side of your results.  The screenshots below have the old interface on the left and the new interface on the right.<br />
<span id="more-1045"></span></p>
<p style="clear: both;"><a href="http://www.poundbangwhack.com/wp-content/uploads/google_old_home.gif"><img src="http://www.poundbangwhack.com/wp-content/uploads/google_old_home-299x222.gif" alt="google_old_home" title="google_old_home" width="299" height="222" class="alignleft size-medium wp-image-1184" /></a><a href="http://www.poundbangwhack.com/wp-content/uploads/google_new_home.gif"><img src="http://www.poundbangwhack.com/wp-content/uploads/google_new_home-299x222.gif" alt="google_new_home" title="google_new_home" width="299" height="222" class="alignleft size-medium wp-image-1178" /></a></p>
<p style="clear: both;"><a href="http://www.poundbangwhack.com/wp-content/uploads/google_old_search_results.gif"><img src="http://www.poundbangwhack.com/wp-content/uploads/google_old_search_results-300x169.gif" alt="google_old_search_results" title="google_old_search_results" width="300" height="169" class="alignleft size-medium wp-image-1183" /></a><a href="http://www.poundbangwhack.com/wp-content/uploads/google_new_search_results.gif"><img src="http://www.poundbangwhack.com/wp-content/uploads/google_new_search_results-300x169.gif" alt="google_new_search_results" title="google_new_search_results" width="300" height="169" class="alignleft size-medium wp-image-1179" /></a></p>
<p style="clear: left;">In order to achieve this look in your browser, first go to <a href="http://google.com">google.com</a>.  If you have an iGoogle home page, make sure you click &#8216;Classic Home&#8217; in the upper right if you want to see the home page differences.  Second, copy and paste the entire code below into your browser&#8217;s address bar:<br />
<code>javascript:void(document.cookie="PREF=ID=20b6e4c2f44943bb<br />:U=4bf292d46faad806:TM=1249677602:LM=1257919388:S=odm0Ys-53ZueXfZG;path=/; domain=.google.com");</code></p>
<p>If you want to set it back to the default, you will need to delete the current cookies for google.com from your browser.  What are your thoughts on this interface? Share them below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poundbangwhack.com/2009/12/07/check-out-googles-new-interface-and-try-it-for-yourself/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mysqldump: Got error: 2008: MySQL client run out of memory when retrieving data from server</title>
		<link>http://www.poundbangwhack.com/2009/12/07/mysqldump-got-error-2008-mysql-client-run-out-of-memory-when-retrieving-data-from-server/</link>
		<comments>http://www.poundbangwhack.com/2009/12/07/mysqldump-got-error-2008-mysql-client-run-out-of-memory-when-retrieving-data-from-server/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 20:44:57 +0000</pubDate>
		<dc:creator>Mark Stoecker</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[mysqldump]]></category>

		<guid isPermaLink="false">http://www.poundbangwhack.com/?p=1138</guid>
		<description><![CDATA[I came across this error today while at work.  While trying to process a MySQL dump of a database of approximately 8 GB in size, I got the following error:
mysqldump: Got error: 2008: MySQL client run out of memory when retrieving data from server
This occurred on a MySQL 4.1 server.  To get around [...]]]></description>
			<content:encoded><![CDATA[<p>I came across this error today while at work.  While trying to process a MySQL dump of a database of approximately 8 GB in size, I got the following error:<br />
<code>mysqldump: Got error: 2008: MySQL client run out of memory when retrieving data from server</code><br />
This occurred on a MySQL 4.1 server.  To get around this, you will need to use the <span class="pre">-q</span> switch as part of your <span class="pre">mysqldump</span> command.</p>
<blockquote cite="http://dev.mysql.com/doc/refman/4.1/en/mysqldump.html#option_mysqldump_quick"><p>This option is useful for dumping large tables. It forces mysqldump to retrieve rows for a table from the server a row at a time rather than retrieving the entire row set and buffering it in memory before writing it out.</p>
<p><em style="font-size: smaller;">(source: <a href="http://dev.mysql.com/doc/refman/4.1/en/mysqldump.html#option_mysqldump_quick" target="_blank">MySQL ::   MySQL 3.23, 4.0, 4.1 Reference Manual :: 4.5.4 mysqldump — A Database Backup Program</a>)</em></p></blockquote>
<p>Your full command should look something like this:<br />
<code>$ mysqldump -u <em>user</em> -p <em>password</em> -q <em>database</em> > <em>outfile.sql</em></code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.poundbangwhack.com/2009/12/07/mysqldump-got-error-2008-mysql-client-run-out-of-memory-when-retrieving-data-from-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>12 Quick and Easy MySQL Tricks</title>
		<link>http://www.poundbangwhack.com/2009/12/05/12-quick-and-easy-mysql-tricks/</link>
		<comments>http://www.poundbangwhack.com/2009/12/05/12-quick-and-easy-mysql-tricks/#comments</comments>
		<pubDate>Sat, 05 Dec 2009 20:26:24 +0000</pubDate>
		<dc:creator>Mark Stoecker</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tricks]]></category>

		<guid isPermaLink="false">http://www.poundbangwhack.com/?p=1068</guid>
		<description><![CDATA[In my first two months as a MySQL DBA, I have picked up a number of tips and tricks that have helped me in my daily job.  In this post, I share them here with everyone.  Hopefully they will help you as much as they have helped me.  ]]></description>
			<content:encoded><![CDATA[<p>In my first two months as a MySQL DBA, I have picked up a number of tips and tricks that have helped me in my daily job.  In this post, I share them here with everyone.  Hopefully they will help you as much as they have helped me.<br />
<span id="more-1068"></span></p>
<h3 style="clear: left;">Run a bash command from the MySQL command line:</h3>
<p>When you are operating in the MySQL command line mode, use the command <strong class="pre">\!</strong> to execute a command as if you were in a normal bash shell.  For instance, to run a <span class="pre">top</span> command from the MySQL command line, run the following code:<br />
<code>mysql>\! top</code></p>
<h3>Kill a long running MySQL query:</h3>
<p>If you have a query that has been running for a long time, you can kill a MySQL query same as you can kill a bash process.  To kill a query, run a <b class="pre">show processlist;</b> to get the process Id.  Then run a <b class="pre">kill</b> command with the Id:</p>
<pre>mysql> show processlist;
+-------+-------+-----------+------+---------+------+-------+--------+
| Id    | User  | Host      | db   | Command | Time | State | Info   |
+-------+-------+-----------+------+---------+------+-------+--------+
| 19638 | admin | localhost | mysql| Sleep   | 23154| NULL  | NULL   |
+-------+-------+-----------+------+---------+------+-------+--------+
1 row in set (0.00 sec)
</pre>
<p><code>mysql>kill 19638;</code></p>
<h3>Cancel the current command you are inputting:</h3>
<p>While operating in a bash command line, you can hit <strong class="pre">Ctrl+C</strong> to cancel your input.  If you execute this in a mysql command line interface, you will close the connection.  Instead, before any query terminators (<strong class="pre"> ; </strong> or <strong class="pre">\G</strong>), end your query with <strong class="pre">\c</strong>:<br />
<code>mysql> select * from mysql.user where user=\c<br />mysql></code></p>
<h3>Change your AUTO_INCREMENT value</h3>
<p>If you&#8217;re like me, you&#8217;ve done some development at one point or another on a live site and wanted to test your code changes.  You execute the code and it inserts your data into your database flawlessly.  Once you&#8217;re ready to implement your changes, you remove the rows you inserted.  However, now you&#8217;ve increased your AUTO_INCREMENT counter a few times and need/want it back where it was.  Find the last auto incremented value, and run a quick alter table to update it:<br />
<code>mysql>SELECT id FROM members ORDER BY id DESC LIMIT 1;<br />
+----+<br />
| id |<br />
+----+<br />
| 82 |<br />
+----+<br />
1 row in set (0.00 sec)<br />
mysql>ALTER TABLE members AUTO_INCREMENT=83;<br />
</code><br />
If you&#8217;re asking, why not run a <strong class="pre">SHOW CREATE TABLE members</strong> query to get the current value, the answer is because that will show the current AUTO_INCREMENT value, after the data you inserted.  You need to find the last value in your table, and set the next AUTO_INCREMENT to be 1 higher than that.  </p>
<h3>Make your query output, more terminal friendly</h3>
<p>As most everyone should know, the command delimiter in MySQL is the semi-colon: <strong class="pre">;</strong>.  However, if you are running a query with lots of column output, for example a <strong class="pre">SELECT *</strong> query, to make your output more readable, terminate your command with a <strong class="pre">\G</strong>:<br />
<code>mysql<br />
mysql> SELECT * FROM mysql.user WHERE User='root' AND Host='localhost'\G<br />
***************** 1. row *****************<br />
                 Host: localhost<br />
                 User: root<br />
             Password: *********************<br />
          Select_priv: Y<br />
          Insert_priv: Y<br />
          Update_priv: Y<br />
          Delete_priv: Y<br />
          ...<br />
1 row in set (0.00 sec)<br />
</code></p>
<h3>Make output from `SHOW PROCESSLIST` more readable</h3>
<p>When you have a very large processlist that causes queries to take up multiple rows and scrolls the screen, you can make it easier to read by paging the output.  By setting the pager to <strong class="pre">less -S</strong>,this will page the output for better readability.  With the <strong class="pre">-S</strong> switch, this will cause lines to display one line instead of wrapping.  By setting the pager, you can navigate output with the arrow keys.  Set output paging with the following command:<br />
<code>mysql>pager less -S</code><br />
To set the pager back, close the mysql connection or run:<br />
<code>mysql>nopager</code></p>
<h3>Retrieve the output of your mysql command in <acronym title="HyperText Markup Language">HTML</acronym> or <acronym title="eXtensible Markup Language">XML</acronym> format</h3>
<p>When running a MySQL command using the command line mysql command, pass the -H or -X switches to receive your output in <acronym title="HyperText Markup Language">HTML</acronym> or <acronym title="eXtensible Markup Language">XML</acronym> output, then store the output in a file.  You can suppress column headers with the &#8211;skip-column-names switch:<br />
<code>$ mysql -u user -p password mysql -e'select * from table' -H --skip-column-names > output.html'<br />$ mysql -u user -p password mysql -e'select * from table' -X --skip-column-names > output.xml'</code></p>
<h3>Skip a one-off error in replication:</h3>
<p>If your MySQL replication is not running and you have determined that the error is a one-off situation, you can tell MySQL to skip the error and continue replication with a simple command.  This command can only be run when the Slave_SQL thread is not running.  This command skips event groups in the binary logs.  In an InnoDB, and other transactional tables, an event group corresponds to an entire transaction.  For nontransactional tables like MyISAM, an event group corresponds to a single statement.  While it is possible to skip more than one error at a time, it si not recommended.  To skip the current error, execute the following command:<br />
<code>mysql>SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE;</code></p>
<h3>Disable binary logging for the current session:</h3>
<p>Let&#8217;s say that you&#8217;re developing on your production data, which many of us do.  In order to prevent your changes from being logged, and therefore replicated, run the following command when you enter the MySQL command line:<br />
<code>mysql>SET SQL_BIN_LOG=0;</code><br />
This is a session variable, meaning it will be re-enabled when you close the session, or you can set it back to 1.</p>
<h3>Load an SQL data dump into MySQL</h3>
<p>Say you have a raw SQL file full of data that you need to import into MySQL.  Assuming your <strong class="pre">CREATE TABLE</strong> statement is part of that code, you can import it directly in one of two ways, either through bash or mysql command line:<br />
<code>$ mysql -u <em>user</em> -p <em>password</em> < <em>/tmp/data_dump.sql</em></code><br />
<code>mysql>LOAD DATA INFILE '<em>/tmp/data_dump.sql</em>';</code></p>
<h3>Tell the optimizer which index you want to use:</h3>
<p>The MySQL Optimizer generally does a great job of executing queries and selecting the right indexes to use.  But let&#8217;s face it, sometimes, it gets it wrong.  In these instances, you can tell MySQL which index to use when executing your query.  The only way to know this however, is to test, test, and test.  You have to know your data (data, indexes, query times, etc).  The only way to find out what index the optimizer is using, is to use the <strong class="pre">EXPLAIN</strong> command on your <strong class="pre">SELECT</strong> query, which is a whole other post.<br />
<code>mysql>SELECT * FROM <em>table</em> USE INDEX (<em>index_name</em>);<br />
</code></p>
<h3>Choose proper columns (and column order) for indexes</h3>
<p>I&#8217;m not going to get into this in depth as indexing tables is it&#8217;s own post.  However, for a quick and dirty indexing solution, try the following.  Say you have the following queries you run regularly on your site with varying <strong class="pre">WHERE</strong> clauses:<br />
<code>mysql>SELECT * FROM table WHERE <em>a=x</em>, <em>b=y</em>, AND <em>c=z</em>;<br />mysql>SELECT * FROM table WHERE <em>a=x</em> AND <em>b=y</em>;<br />mysql>SELECT * FROM table WHERE <em>a=x</em>;</code><br />
At first thought, you may just think to use a covering index that will satisfy all 3 queries:<br />
<code>mysql>ALTER TABLE table ADD INDEX (a,b,c);</code><br />
However this may not be the best solution.  The covering index is correct, but the order may not be.  The point of an index is to speed up query processing time by returning as few rows as possible.  If you have 10,000 rows in your database, and the <strong class="pre">WHERE</strong> clause <em class="pre">a=x</em> satisfies 9,500 of those rows, you aren&#8217;t making MySQL&#8217;s job any easier.  What you want to do is find out which of your conditions returns the fewest rows because then, you&#8217;re running additional conditions on a smaller data set and your query runs faster.  For example, <em class="pre">a=x</em> may satisfy 9,500 rows and then of those 9,500 <em class="pre">b=y</em> may satisfy 5,000.  After <em class="pre">a=x</em>, you&#8217;re running the next condition on 9,500 rows of data.  However, if <em class="pre">b=y</em> satisfies 6,000 rows initially and <em class="pre">a=x</em> then satisfies 5,000 of those, you&#8217;re query will run faster.  This is because your second condition is run on fewer rows, meaning faster processing times.  This can all still be done through a covering index, but you need to find out which of your conditions is the most restrictive.  To do that, run the following command:<br />
<code>mysql>SELECT SUM(<em>a=x</em>), SUM(<em>b=y</em>), SUM(<em>c=z</em>) FROM table;</code><br />
What this will do is tell you the total number of rows that satisfy each condition.  So if your output looks like this:</p>
<pre>mysql>SELECT SUM(<em>a=x</em>), SUM(<em>b=y</em>), SUM(<em>c=z</em>) FROM table;
+----------+----------+----------+
| SUM(<em>a=x</em>) | SUM(<em>b=y</em>) | SUM(<em>c=z</em>) |
+----------+----------+----------+
|    10000 |     6000 |       17 |
+----------+----------+----------+
1 row in set (0.00 sec)
</pre>
<p>Then <em>c=z</em> condition is the most restrictive and so <em>c</em> should be the first column in your covering index.  Run your query again, this time with a <strong class="pre">WHERE</strong> clause of <em>c=z</em> to find the second most restrictive condition, and so on and so forth.<br />
<code>mysql>SELECT SUM(<em>a=x</em>), SUM(<em>b=y</em>), SUM(<em>c=z</em>) FROM table WHERE <em>c=z</em>;</code> and you may get</p>
<pre>mysql>SELECT SUM(<em>a=x</em>), SUM(<em>b=y</em>), SUM(<em>c=z</em>) FROM table WHERE <em>c=z</em>;
+----------+----------+----------+
| SUM(<em>a=x</em>) | SUM(<em>b=y</em>) | SUM(<em>c=z</em>) |
+----------+----------+----------+
|        5 |        2 |       17 |
+----------+----------+----------+
1 row in set (0.00 sec)
</pre>
<p>From here, <em>b=y</em> is the next most restrictive condition.  So your index should be built like this:<br />
<code>ALTER TABLE table ADD INDEX (c,b,a)</code> and your queries will run faster.</p>
<p>The one drawback to this is that if <em>c</em> is the first column in your index, but it is not specified in the <strong class="pre">WHERE</strong> clause, as in the first two queries above, the index will be ignored.  The only way to remedy this, is to create another index for those two queries, whereas the initial <em>(a,b,c)</em> index would satisfy all queries.  The only way to determine which solution works best for you is to benchmark each option.</p>
<p>If you have any MySQL Tips or tricks of your own, please share them in the comments below to help everyone out.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poundbangwhack.com/2009/12/05/12-quick-and-easy-mysql-tricks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Top 20+ MySQL Best Practices</title>
		<link>http://www.poundbangwhack.com/2009/12/04/top-20-mysql-best-practices/</link>
		<comments>http://www.poundbangwhack.com/2009/12/04/top-20-mysql-best-practices/#comments</comments>
		<pubDate>Fri, 04 Dec 2009 07:00:18 +0000</pubDate>
		<dc:creator>Mark Stoecker</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Optimization]]></category>

		<guid isPermaLink="false">http://www.poundbangwhack.com/?p=1041</guid>
		<description><![CDATA[I came across an excellent article a couple days ago in my <a href="http://feeds.feedburner.com/nettuts">NetTuts+ RSS Feed</a> titled "Top 20+ MySQL Best Practices".  In the article, author <a href="http://www.phpandstuff.com/">Burak Guzel</a> gives some <strong>excellent MySQL tips</strong>.  Due to my argumentative nature (not really) I made a few comments on the post that you can see at the bottom about 1 or 2 of the tips.  The tips were by no means wrong, I just wanted to add some clarification and caveats to them.  A couple of the tips, I have been using every single day in my job and they have proven invaluable.  The article is excellent and I highly recommend reading it.]]></description>
			<content:encoded><![CDATA[<p>I came across an excellent article a couple days ago in my <a href="http://feeds.feedburner.com/nettuts">NetTuts+ RSS Feed</a> titled &#8220;Top 20+ MySQL Best Practices&#8221;.  In the article, author <a href="http://www.phpandstuff.com/">Burak Guzel</a> gives some <strong>excellent MySQL tips</strong>.  Due to my argumentative nature (not really) I made a few comments on the post that you can see at the bottom about 1 or 2 of the tips.  The tips were by no means wrong, I just wanted to add some clarification and caveats to them.  A couple of the tips, I have been using every single day in my job and they have proven invaluable.  The article is excellent and I highly recommend reading it.<br />
<span id="more-1041"></span></p>
<blockquote><p><strong><a href="http://net.tutsplus.com/tutorials/other/top-20-mysql-best-practices/">Top 20+ MySQL Best Practices</a></strong></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.poundbangwhack.com/2009/12/04/top-20-mysql-best-practices/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Where do you find your reading material?</title>
		<link>http://www.poundbangwhack.com/2009/12/03/where-do-you-find-your-reading-material/</link>
		<comments>http://www.poundbangwhack.com/2009/12/03/where-do-you-find-your-reading-material/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 07:00:48 +0000</pubDate>
		<dc:creator>Mark Stoecker</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[learning]]></category>
		<category><![CDATA[Mozilla Thunderbird]]></category>
		<category><![CDATA[RSS]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://www.poundbangwhack.com/?p=1039</guid>
		<description><![CDATA[Anyone who is at the very least semi-serious about growing their blog, or learning more about their subject, knows, you never stop reading.  There is always something on the internet worth reading in your niche and anyone who says otherwise is either a liar, in denial, or not looking hard enough to find it.  <strong>The information is out there and it won't come to you, you have to go and find it.</strong>]]></description>
			<content:encoded><![CDATA[<p>Anyone who is at the very least semi-serious about growing their blog, or learning more about their subject, knows, you never stop reading.  There is always something on the internet worth reading in your niche and anyone who says otherwise is either a liar, in denial, or not looking hard enough to find it.  <strong>The information is out there and it won&#8217;t come to you, you have to go and find it.</strong><br />
<span id="more-1039"></span><br />
That being said, I have two main sources for my information: <abbr title="Really Simple Syndication">RSS</abbr> Feeds and Twitter.  However, the majority of the people that I follow on Twitter, I also subscribe to their RSS Feed.  I know with using Twitter, I have the advantage of seeing ReTweets from the people I&#8217;m following, but I like the convenience of RSS better as I use <a href="http://www.mozillamessaging.com/en-US/thunderbird/">Mozilla Thunderbird</a> to subscribe to feeds so I get them with my email (they&#8217;re in separate folders so they don&#8217;t conflict with each other if you&#8217;re wondering).  I currently subscribe to close to 70+ RSS feeds and about half are updated daily.  I previously posed the question <a href="http://www.poundbangwhack.com/2009/06/05/is-twitter-the-rss-killer/">Is Twitter the RSS Killer?</a> Maybe it is, maybe it isn&#8217;t, however, as I mentioned above, I actually prefer RSS for a number of reasons.  </p>
<p>What I&#8217;m wondering is, as the title suggests, where do you find your &#8220;reading material&#8221;?  What is your blog, your business, your site, your whatever, about and what do you find to be the most effective means of finding new information, whether it&#8217;s for your site, or for your personal learning?  Please share and hopefully we can all find some new means of gathering information.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poundbangwhack.com/2009/12/03/where-do-you-find-your-reading-material/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Avoid WordPress StatPress plugin like the plague!</title>
		<link>http://www.poundbangwhack.com/2009/12/02/avoid-wordpress-statpress-plugin-like-the-plague/</link>
		<comments>http://www.poundbangwhack.com/2009/12/02/avoid-wordpress-statpress-plugin-like-the-plague/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 07:44:58 +0000</pubDate>
		<dc:creator>Mark Stoecker</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Wordpress Plugins]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[StatPress]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.poundbangwhack.com/?p=1036</guid>
		<description><![CDATA[I'll agree that the features of the plugin are nice, including the real-time monitoring, the GUI, and the sheer amount of data collected.  However, the design flaws mentioned previously can spell disaster for your website, especially if it is a popular site.  The information provided by the StatPress plugin is useful.  However, when you scratch just below the surface of this plugin, beyond the stats, the plugin itself is horrible.]]></description>
			<content:encoded><![CDATA[<p>The WordPress plugin StatPress is an absolutely <strong>horrid</strong> plugin to use. Yes, I said it&#8230;<strong>horrid!</strong>  After seeing many people praising this plugin on their sites, this is a bold statement.<br />
<span id="more-1036"></span><br />
As anyone who <a href="http://www.google.com/search?hl=en&#038;source=hp&#038;q=Mark+Stoecker&#038;aq=f&#038;oq=&#038;aqi=g10">google&#8217;s my name</a>, you&#8217;ll see that I’m a MySQL <acronym title="Database Administrator">DBA</acronym> for <a href="http://www.godaddy.com">GoDaddy.com</a>.  My primary responsibilities include managing our shared hosting MySQL servers.  In my job I see people using StatPress on their <a href="http://www.wordpress.org">WordPress blogs</a> and it <strong>kills the performance of the server, and their site.</strong>  Not only does it store massive amounts of data (if you don&#8217;t change the settings), but the database design is just downright horrible.  A second version of this plugin, called StatPress Reloaded, does not resolve any of the design flaws prevalent in the original StatPress plugin.  Tables and columns that are regularly queried are missing integral indexes that can improve performance. Additionally, all data fields are by default TEXT (TEXT or TINYTEXT in SP Reloaded) data type, which is BAD!  This plugin should be avoided at all costs.</p>
<p>By changing a few data types and adding a couple indexes, I’ve taken queries from this plugin from examining 140k plus rows, down to examining less than 1800 rows, a 78% decrease in rows examined. Instead, I recommend “<a href="http://wordpress.org/extend/plugins/google-analytics-for-wordpress/">Google Analytics for WordPress</a>” or “<a href="http://wordpress.org/extend/plugins/stats/">Wordpress.com Stats</a>” (the latter requires an API key from <a href="http://www.wordpress.com">wordpress.com</a>, the former is obviously used in conjunction with Google Analytics, which is a great stat tracking software).</p>
<p>I&#8217;ll agree that the features of the plugin are nice, including the real-time monitoring, the GUI, and the sheer amount of data collected.  However, the design flaws mentioned previously can spell disaster for your website, especially if it is a popular site.  The information provided by the StatPress plugin is useful.  However, when you scratch just below the surface of this plugin, beyond the stats, the plugin itself is horrible.</p>
<p>I installed this plugin today to start tinkering with it to know it better so I could improve it.  After only 9 hours of collecting data, I have 270 rows of data on a blog that receives only minor traffic.  That&#8217;s approximately 720 rows of data per day and 21600 rows of data per month, and nearly 130,000 rows of data in 6 months.  Anyone who knows anything about database design, querying a table with 130,000 rows of data and no index can spell disaster for your blog.  And that&#8217;s only on a minor traffic blog.  If your site gets more traffic than that, you&#8217;re in serious trouble.</p>
<p>I am currently working on fixing all the faults in the database design and query execution of this plugin and will post here once I have, as well as on WordPress.org.  If you have further questions or comments about this plugin, please post them here and I will do my best to answer.</p>
<p>You may wonder why I didn&#8217;t link to the WordPress.org plugins page or the developer&#8217;s home pages for these plugins, but it&#8217;s because I don&#8217;t want to send traffic to them as, since i mentioned, they are not useful plugins.  You can find them and install them on your own if you want, but as you can tell, I wouldn&#8217;t recommend it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poundbangwhack.com/2009/12/02/avoid-wordpress-statpress-plugin-like-the-plague/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
