<?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>Ian Dunn &#187; MySQL</title>
	<atom:link href="http://iandunn.name/category/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://iandunn.name</link>
	<description>Seattle-based web developer blogging about tips and solutions</description>
	<lastBuildDate>Sat, 04 Feb 2012 00:22:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>Performance Improvements for Dedicated WordPress Servers</title>
		<link>http://iandunn.name/performance-improvements-for-dedicated-wordpress-servers/</link>
		<comments>http://iandunn.name/performance-improvements-for-dedicated-wordpress-servers/#comments</comments>
		<pubDate>Wed, 03 Aug 2011 20:45:14 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Benchmarks]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[PHP-APC]]></category>

		<guid isPermaLink="false">http://iandunn.name/?p=952</guid>
		<description><![CDATA[Mark Maunder <a title="The Basic WordPress Speedup" href="http://markmaunder.com/2011/the-basic-wordpress-speedup/">benchmarked several performance tuning measures</a> with a WordPress installation on a VPS server to show which are most effective. The biggest improvements were from installing <a href="http://php.net/manual/en/book.apc.php">PHP-APC</a> , setting up <a href="http://nginx.org/">Nginx</a> to proxy concurrent connections for Apache, and using MySQL&#8217;s query cache. &#160;]]></description>
			<content:encoded><![CDATA[<p>Mark Maunder <a title="The Basic WordPress Speedup" href="http://markmaunder.com/2011/the-basic-wordpress-speedup/">benchmarked several performance tuning measures</a> with a WordPress installation on a VPS server to show which are most effective. The biggest improvements were from installing <a href="http://php.net/manual/en/book.apc.php">PHP-APC</a>, setting up <a href="http://nginx.org/">Nginx</a> to proxy concurrent connections for Apache, and using MySQL&#8217;s query cache.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://iandunn.name/performance-improvements-for-dedicated-wordpress-servers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Comprehensive WordPress Multisite Migrations</title>
		<link>http://iandunn.name/comprehensive-wordpress-multisite-migrations/</link>
		<comments>http://iandunn.name/comprehensive-wordpress-multisite-migrations/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 02:44:25 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Subscribe2]]></category>
		<category><![CDATA[WordCamp Phoenix]]></category>
		<category><![CDATA[Wordpress Multisite]]></category>

		<guid isPermaLink="false">http://iandunn.name/workblog/?p=417</guid>
		<description><![CDATA[Migrating multiple standalone installations of WordPress into <a title="Wordpress Multisite" href="http://codex.wordpress.org/Create_A_Network">Multisite</a> can be relatively easy if you don’t need it to be perfect. The Codex has <a title="Migrating a site to WordPress Multisite" href="http://codex.wordpress.org/Migrating_Multiple_Blogs_into_WordPress_3.0_Multisite">a basic guide</a> and Stephanie Leary gave <a title="Advanced tips on WordPress Multisite migrations" href="http://wordpress.tv/2011/01/29/stephanie-leary-tricky-migrations/">some more detailed tips</a> at Wordcamp Phoenix 2011. But I’ve been working on a project for a client who had half a dozen blogs with hundreds of users and thousands of posts, and... [<a href="http://iandunn.name/comprehensive-wordpress-multisite-migrations/">more</a>]]]></description>
			<content:encoded><![CDATA[<p>Migrating multiple standalone installations of WordPress into <a title="Wordpress Multisite" href="http://codex.wordpress.org/Create_A_Network">Multisite</a> can be relatively easy if you don’t need it to be perfect. The Codex has <a title="Migrating a site to WordPress Multisite" href="http://codex.wordpress.org/Migrating_Multiple_Blogs_into_WordPress_3.0_Multisite">a basic guide</a> and Stephanie Leary gave <a title="Advanced tips on WordPress Multisite migrations" href="http://wordpress.tv/2011/01/29/stephanie-leary-tricky-migrations/">some more detailed tips</a> at Wordcamp Phoenix 2011.</p>
<p>But I’ve been working on a project for a client who had half a dozen blogs with hundreds of users and thousands of posts, and they wanted the migration to be completely transparent for the users and readers. That meant that user passwords must remain in tact, duplicate users had to be merged, plugin data had to be migrated, etc. None of that would have been possible with the standard methods, so I had to work out a process that would include everything, and I’ve written up a detailed description of it below.</p>
<p>This assumes that you have some intermediate knowledge of MySQL and tweaking plugins/themes, that the new Multisite installation is on the same server as the standalone ones, and that the new WPMS blog will live at the same URL as the old standalone blog did. I’m also assuming that you’re using phpMyAdmin to do some basic things like copying tables and data. so I haven’t included the queries for those. I’ve refined this process over a dozen iterations, but you may need to tweak it here and there to fit your context, and you may run into situations that I didn’t because of specific plugins you’re using, etc. I&#8217;d recommend trying it out on a development server first and then pushing to production once you&#8217;re convinced it&#8217;s all sorted.</p>
<p style="text-align: center;">* * *</p>
<p style="text-align: left;"><strong>Step 1<br />
</strong>Rename the old blog directory from <em>foo</em> to <em>_old_foo</em>. In the wp_options table, update the <em>siteurl, home and upload_path</em> options to reflect the new path. The old blog is now running in at a different URL, so you can use it to compare against the new one at the end. If you don’t update <em>upload_path</em> then WP will recreate the upload directory in the old space, which will prevent WPMS from using it.</p>
<p><strong>Step 2<br />
</strong>Backup the old standalone database and also the WPMS database (unless this is the first blog you’re migrating into WPMS).</p>
<p><strong>Step 3</strong><br />
If the standalone blog is significantly older than the WPMS install, upgrade it to match the WPMS version. I’ve had good luck migrating 2.9 and above into 3.0.5, but have been upgrading anything older than 2.9 to 3.0.5 before migrating.</p>
<p><strong>Step 4</strong><br />
Install the plugins and theme that the blog uses into WPMS, and activate the theme on the Super Admin &gt; Themes page.  If you’re using a distributed theme (rather than a custom one) and it’s been modified, you’ll want to either create a child theme with the modifications, or rename the theme’s folder from <em>foo</em> to <em>foo-bar</em> and update the style.css to reflect the new name. Otherwise you might run into conflicts if multiple blogs have uniquely modified versions of the same theme. You’ll also want to check the theme for any hardcoded URLs, paths, etc and replace them with the proper method, e.g., bloginfo(), STYLESHEETPATH, etc.</p>
<p>You may want to upgrade any plugins to the latest version to help avoid any incompatibles with WPMS. If you’ve modified a plugin differently across different standalone installations then you’ll need to merge them into a single instance, or give the plugins unique names and metadata. Don&#8217;t activate them yet, though, because they might mess some things up since their data isn&#8217;t imported yet. They&#8217;ll be activated when we import the options table.</p>
<p><strong>Step 5</strong><br />
Create the empty blog in WPMS. Make a mental note of the ID, because we’ll use it extensively. The site address can’t have an underscore in it, so you’ll have to use a dash or something else instead.</p>
<p><strong>Step 6</strong><br />
Copy the plugin tables from <em>wp_plugin_name</em> to <em>wp_ID_plugin_name</em>, using the ID from step 5.</p>
<p><strong>Step 7</strong><br />
Empty all of the <em>wp_ID_*</em> tables in the WPMS database, but leave <em>wp_users </em>and <em>wp_usermeta</em> alone.</p>
<p><strong>Step 8</strong><br />
Copy the data from the old options table straight into the new <em>wp_ID_options </em>table. Edit the<em> siteurl, home and upload_path</em> values. WPMS stores files in <em>wp-content/blogs.dir/ID/files</em> instead of <em>wp-content/uploads</em>. Rename the <em>wp_user_roles</em> column to <em>wp_ID_user_roles</em>.</p>
<p><strong>Step 9</strong><br />
Copy the data for <em>wp_commentmeta, wp_postmeta,  wp_terms, wp_term_relationships, </em>and <em>wp_term_taxonomy</em> straight into their corresponding WPMS tables. Update the <em>wp_attached_file </em>data in<em> wp_postmeta</em> to match the new file path if any of it&#8217;s records contain the old path:</p>
<pre class="brush: sql; title: ; notranslate">
UPDATE wp_ID_postmeta
SET wp_attached_file = replace(
	wp_attached_file,
	'wp-content/uploads/',
	'wp-content/blogs.dir/ID/files/'
)
</pre>
<p><strong>Step 10</strong><br />
Copy <em>wp_links </em>to a temp table, like<em> _ID_links</em>, and drop the<em> link_category</em> column from the temp table if it exists. Then copy the data into <em>wp_ID_links </em>and drop the temp table.</p>
<p>And now it&#8217;s going to get a little more involved. WPMS stores all blog-specific data in the blog’s own set of tables, but users are shared across the entire network and are stored in a common table. If you try to copy all of the users from various blogs to that table, the IDs will conflict. The way we get around that is to come up with a prefix for each blog, and add it to the various IDs involved. For example, the prefix for the first blog is 1000, so user ID<em> </em>1 becomes 1001; the prefix for the second blog is 2000, so user ID 5 becomes 2005, etc. You’ll want to make sure that the prefixes are large enough to not overlap, so if the first blog has 1200 <em>wp_usermeta</em> records, then its highest <em>umeta_id</em> would be 2200, and you’d want to skip the 2000 prefix and use 3000 for the second blog.</p>
<p><strong>Step 11</strong><br />
Copy <em>wp_users</em> to a temporary table like<em> _ID_users</em> and delete the admin user (because WPMS has its own already). Update the IDs with the prefix,</p>
<pre class="brush: sql; title: ; notranslate">
UPDATE _ID_users
SET ID = ID + [prefix]
</pre>
<p>Add two columns to the end of the table<em>, spam and deleted</em>. Both are<em> TINYINT(2)</em>. Check for duplicate users already in the WPMS table:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT user_email FROM wp_users
WHERE user_email IN (SELECT user_email FROM _ID_users)
</pre>
<p>If you have duplicate users, make a note of their current usernames and IDs, and then delete them from the temp table. Then copy the data into <em>wp_users </em>and delete the temporary table.</p>
<p><strong>Step 12</strong><br />
Copy <em>wp_usermeta </em>to<em> _ID_usermeta</em>, delete the values for the admin user, update the IDs and rename a few keys:</p>
<pre class="brush: sql; title: ; notranslate">
DELETE FROM _ID_usermeta
WHERE user_id = 1

UPDATE _ID_usermeta
SET user_id = user_id + [prefix]

UPDATE _ID_usermeta
SET umeta_id = umeta_id + [prefix]

UPDATE _ID_usermeta
SET meta_key = ‘wp_ID_user_level’
WHERE meta_key = ‘wp_user_level’

UPDATE _ID_usermeta
SET meta_key = ‘wp_ID_capabilities’
WHERE meta_key = ‘wp_capabilities’
</pre>
<p>If you have any duplicate users, update their IDs (which you wrote down in step 11) to match the ones already in the <em>wp_users </em>table.</p>
<pre class="brush: sql; title: ; notranslate">
UPDATE _ID_usermeta
SET user_id = 14
WHERE user_id = 1005
</pre>
<p>In that query, 14 would be the ID of the user already in WPMS, and 1005 would be the ID of the corresponding duplicate user in blog we’re currently migrating. Then remove all of the rows in <em>_ID_users </em>for the duplicate user, except for<em> wp_ID_user_level</em> and <em>wp_ID_capabilities</em>.</p>
<p>The copy the data into wp_users and drop the temporary table.</p>
<p><strong>Step 13</strong><br />
Copy <em>wp_posts </em>to<em> _ID_posts</em> and drop the<em> post_category</em> column if it exists. Update the<em> post_author</em> IDs with the same prefix as before (with the exception of the admin user):</p>
<pre class="brush: sql; title: ; notranslate">
UPDATE _ID_posts
SET post_author = post_author + [prefix]
WHERE post_author != 1
</pre>
<p>If you have duplicate users, update their <em>post_author </em>IDs just like we did in the previous step. Then copy the data into <em>wp_ID_posts</em> and delete the temp table.</p>
<p>Copy all of the files from the old blog’s <em>wp-content/uploads </em>directory into the new<em> wp-content/blogs.dir/ID/files </em>directory. This’ll be a lot faster and easier if you have SSH access to the server, but if you don’t you can pull them down to your local machine and re-upload them.</p>
<p>Now we’ll need to update any references to the old files in posts:</p>
<pre class="brush: sql; title: ; notranslate">
UPDATE wp_ID_posts
SET post_content = replace(
	post_content,
	'wp-content/uploads/',
	'wp-content/blogs.dir/ID/files/'
)

UPDATE wp_ID_posts
SET guid = replace(
	guid,
	'wp-content/uploads/',
	'wp-content/blogs.dir/ID/files/'
)
</pre>
<p><strong>Step 14<br />
</strong>Copy <em>wp_comments </em>to <em>_ID_comments</em> and update the<em> user_id</em> fields for any comments left by registered users,</p>
<pre class="brush: sql; title: ; notranslate">
UPDATE _ID_comments
SET user_id = user_id + [prefix]
WHERE user_id &gt; 1
</pre>
<p>If you have duplicate users then update the IDs in the same way you did for the previous steps. Then copy the data to<em> wp_ID_comments </em>and drop the temporary table.</p>
<p><strong>Step 15<br />
</strong>Update plugin data. Obviously this will depend on what plugins you’re using, but I’ll use <a href="http://subscribe2.wordpress.com">Subscribe2</a> as an example. Subscribe2 allows people to get e-mail notification when new posts are created, and it stores the subscription data in two different places. Users who don’t have a WP account are stored in the <em>wp_ID_subscribe2 </em>table, and the only thing you need to do for them is copy the table to your WPMS database. Registered users are stored in <em>wp_ID_options</em>, though, and you’ll need to update the meta keys it stores on individual blogs, but not the global ones:</p>
<pre class="brush: sql; title: ; notranslate">
UPDATE wp_usermeta
SET meta_key = CONCAT(‘wp_ID_’, meta_key)
WHERE
	meta_key LIKE ‘%s2%’ AND
	meta_key != ‘s2_format’ AND
	meta_key != ‘s2_autosub’ AND
	user_id &gt; [prefix]
</pre>
<p>If you had any duplicate users, you’ll need to update them manually, because their IDs will be lower than the prefix.</p>
<p>And that&#8217;s it. Now that all of the data is imported, you can log in to WPMS and compare it side by side with the old blog to make sure that nothing was missed or broken. If you renamed your theme you’ll need to reapply your widgets.</p>
]]></content:encoded>
			<wfw:commentRss>http://iandunn.name/comprehensive-wordpress-multisite-migrations/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using the Underscore in MySQL Queries</title>
		<link>http://iandunn.name/using-the-underscore-in-mysql-queries/</link>
		<comments>http://iandunn.name/using-the-underscore-in-mysql-queries/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 07:49:18 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://iandunn.name/workblog/?p=400</guid>
		<description><![CDATA[The underscore is a special character in MySQL, and it can be used to match any character in comparison operations. If you&#8217;re not aware of this, it can <a href="http://ask.webcheatsheet.com/questions/51/mysql-why-like-treats-dash-and-undescore-as-the-same-character">throw you off</a> when trying to search for it inside records.]]></description>
			<content:encoded><![CDATA[<p>The underscore is a special character in MySQL, and it can be used to match any character in comparison operations. If you&#8217;re not aware of this, it can <a href="http://ask.webcheatsheet.com/questions/51/mysql-why-like-treats-dash-and-undescore-as-the-same-character">throw you off</a> when trying to search for it inside records.</p>
]]></content:encoded>
			<wfw:commentRss>http://iandunn.name/using-the-underscore-in-mysql-queries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Backing Up Files and MySQL Databases on Linux Servers</title>
		<link>http://iandunn.name/backing-up-files-and-mysql-databases-on-linux-servers/</link>
		<comments>http://iandunn.name/backing-up-files-and-mysql-databases-on-linux-servers/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 03:56:33 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Linux / Unix]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Backup]]></category>

		<guid isPermaLink="false">http://iandunn.name/workblog/?p=396</guid>
		<description><![CDATA[You&#8217;d think I&#8217;d have this memorized by now, but I always mess up the syntax and have to spend a few minutes digging through man pages or wading through search results to find it. tar -czf [output-file.tar.gz] [input-directory]/ mysqldump -u [username] -p [database name] &#62; [filename]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;d think I&#8217;d have this memorized by now, but I always mess up the syntax and have to spend a few minutes digging through man pages or wading through search results to find it.</p>
<p>tar -czf [output-file.tar.gz] [input-directory]/<br />
mysqldump -u [username] -p [database name] &gt; [filename]</p>
]]></content:encoded>
			<wfw:commentRss>http://iandunn.name/backing-up-files-and-mysql-databases-on-linux-servers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>myisamchk Error 22 on Windows</title>
		<link>http://iandunn.name/myisamchk-error-22-on-windows/</link>
		<comments>http://iandunn.name/myisamchk-error-22-on-windows/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 22:29:44 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://iandunn.name/workblog/?p=379</guid>
		<description><![CDATA[If you want to repair tables in a MySQL database, the docs say that you can just run <a href="http://dev.mysql.com/doc/refman/5.5/en/crashing.html">myisamchk &#8211;silent &#8211;force */*.MYI</a> . That <a href="http://bugs.mysql.com/bug.php?id=29248">doesn&#8217;t work</a> under all version of MySQL for Windows, though, so you may get an error saying, &#8220;Error: 22 when opening MyISAM-table &#8216;*.MYI&#8217;. &#8221; If you do, you can run this command instead: FOR %G IN (dir... [<a href="http://iandunn.name/myisamchk-error-22-on-windows/">more</a>]]]></description>
			<content:encoded><![CDATA[<p>If you want to repair tables in a MySQL database, the docs say that you can just run <em><a href="http://dev.mysql.com/doc/refman/5.5/en/crashing.html">myisamchk &#8211;silent &#8211;force */*.MYI</a></em>. That <a href="http://bugs.mysql.com/bug.php?id=29248">doesn&#8217;t work</a> under all version of MySQL for Windows, though, so you may get an error saying, &#8220;<em>Error: 22 when opening MyISAM-table &#8216;*.MYI&#8217;</em>. &#8221; If you do, you can run this command instead: <em>FOR %G IN (dir \b c:\mysql\data\mydb\*.myi) DO myisamchk -r -f %G</em></p>
]]></content:encoded>
			<wfw:commentRss>http://iandunn.name/myisamchk-error-22-on-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Service Crashes After Drive Failure</title>
		<link>http://iandunn.name/mysql-service-crashes-after-drive-failure/</link>
		<comments>http://iandunn.name/mysql-service-crashes-after-drive-failure/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 20:31:34 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Backup]]></category>

		<guid isPermaLink="false">http://iandunn.name/workblog/?p=371</guid>
		<description><![CDATA[If a hard drive fails while MySQL is trying to write to the disk, the database could get corrupted. If that happens then you might see the MySQL service crashing every time when the first request is made after it starts. The <a href="http://dev.mysql.com/doc/refman/5.5/en/error-log.html">error log</a> might display something like this: InnoDB: Database was not shut down normally! InnoDB:... [<a href="http://iandunn.name/mysql-service-crashes-after-drive-failure/">more</a>]]]></description>
			<content:encoded><![CDATA[<p>If a hard drive fails while MySQL is trying to write to the disk, the database could get corrupted. If that happens then you might see the MySQL service crashing every time when the first request is made after it starts. The <a href="http://dev.mysql.com/doc/refman/5.5/en/error-log.html">error log</a> might display something like this:</p>
<div style="margin-left: 30px; font-style: italic; font-size: .9em;">InnoDB: Database was not shut down normally!<br />
InnoDB: Starting crash recovery.<br />
InnoDB: Restoring possible half-written data pages from the doublewrite<br />
InnoDB: buffer&#8230;<br />
InnoDB: Doing recovery: scanned up to log sequence number 0 373839829<br />
InnoDB: Assertion failure in thread 4868 in file .\trx\trx0purge.c line 476<br />
InnoDB: Failing assertion: trx_sys-&gt;rseg_history_len &gt;= n_removed_logs<br />
InnoDB: We intentionally generate a memory trap.<br />
mysqld got exception 0xc0000005 ;<br />
InnoDB: Database was not shut down normally!<br />
InnoDB: Starting crash recovery.<br />
InnoDB: Restoring possible half-written data pages from the doublewrite<br />
InnoDB: buffer&#8230;InnoDB: Doing recovery: scanned up to log sequence number 0373839829<br />
InnoDB: Assertion failure in thread 4868 in file .\trx\trx0purge.c line 476<br />
InnoDB: Failing assertion: trx_sys-&gt;rseg_history_len &gt;= n_removed_logs<br />
InnoDB: We intentionally generate a memory trap.<br />
mysqld got exception 0xc0000005 ;</div>
<p>You can try backing up and recreating the databases to fix it. Edit my.ini and set <a href="http://dev.mysql.com/doc/refman/5.1/en/forcing-innodb-recovery.html">innodb_force_recovery = 4</a> in the [mysqld] section to prevent MySQL from crashing. Then do a mysqldump*, drop the databases and then import them from the backup.</p>
<p>If that doesn&#8217;t work, the docs have <a href="http://dev.mysql.com/doc/refman/5.5/en/crashing.html">some other tips</a>.</p>
<p><em>* The dump won&#8217;t include any corrupted data, so it might also be a good idea to backup the entire data directory in case you need to try to recover the corrupted data later on.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://iandunn.name/mysql-service-crashes-after-drive-failure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Troubleshooting Slow MySQL Queries</title>
		<link>http://iandunn.name/troubleshooting-slow-mysql-queries/</link>
		<comments>http://iandunn.name/troubleshooting-slow-mysql-queries/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 17:33:01 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[EXPLAIN]]></category>
		<category><![CDATA[indexes]]></category>

		<guid isPermaLink="false">http://iandunn.name/workblog/?p=328</guid>
		<description><![CDATA[Ian Gilfillan&#8217;s article on <a href="http://www.databasejournal.com/features/mysql/article.php/1382791/Optimizing-MySQL-Queries-and-Indexes.htm">using indexes in MySQL</a> has a good explanation of how to use the EXPLAIN statement to analyze a query, and what to look out for. You can also check out Jesse Farmer&#8217;s <a href="http://20bits.com/articles/10-tips-for-optimizing-mysql-queries-that-dont-suck/">optimization tips</a> for a primer on more advanced techniques.]]></description>
			<content:encoded><![CDATA[<p>Ian Gilfillan&#8217;s article on <a href="http://www.databasejournal.com/features/mysql/article.php/1382791/Optimizing-MySQL-Queries-and-Indexes.htm">using indexes in MySQL</a> has a good explanation of how to use the EXPLAIN statement to analyze a query, and what to look out for. You can also check out Jesse Farmer&#8217;s <a href="http://20bits.com/articles/10-tips-for-optimizing-mysql-queries-that-dont-suck/">optimization tips</a> for a primer on more advanced techniques.</p>
]]></content:encoded>
			<wfw:commentRss>http://iandunn.name/troubleshooting-slow-mysql-queries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Natural Sorting for MySQL</title>
		<link>http://iandunn.name/natural-sorting-for-mysql/</link>
		<comments>http://iandunn.name/natural-sorting-for-mysql/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 16:38:02 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://iandunn.name/workblog/?p=242</guid>
		<description><![CDATA[MySQL doesn&#8217;t provide a way to perform <a href="http://sourcefrog.net/projects/natsort/">natural sorting</a> on a string, so if you have numbers in your data you may get results like this Product 110 Product 120 Product 13 Product 140 There are a lot of hacks available, but all of the ones I&#8217;ve seen only work in specific circumstances. The only comprehensive solution... [<a href="http://iandunn.name/natural-sorting-for-mysql/">more</a>]]]></description>
			<content:encoded><![CDATA[<p>MySQL doesn&#8217;t provide a way to perform <a href="http://sourcefrog.net/projects/natsort/">natural sorting</a> on a string, so if you have numbers in your data you may get results like this</p>
<p style="padding-left: 30px;">Product 110<br />
Product 120<br />
Product 13<br />
Product 140</p>
<p>There are a lot of hacks available, but all of the ones I&#8217;ve seen only work in specific circumstances. The only comprehensive solution I found to do the sorting in MySQL is <a href="http://drupal.org/project/natsort">Drupal&#8217;s natsort module</a>. You don&#8217;t need to be running Drupal to use it, just issue the queries that create the function and it&#8217;s dependencies, and you can then call it in your regular queries. But, it requires MySQL 5, so if you&#8217;re working on an older server and your data doesn&#8217;t work with one of the hacks, then you&#8217;ll probably just have to do the natural sorting in your scripting language, using something like <a href="http://us2.php.net/manual/en/function.natsort.php">PHP&#8217;s natsort()</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://iandunn.name/natural-sorting-for-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Passing dates and times between PHP and MySQL</title>
		<link>http://iandunn.name/passing-dates-and-times-between-php-and-mysql/</link>
		<comments>http://iandunn.name/passing-dates-and-times-between-php-and-mysql/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 21:59:35 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://iandunn.name/workblog/?p=125</guid>
		<description><![CDATA[Richard Lord wrote a good article explaining the various ways of <a href="http://www.bigroom.co.uk/blog/dates-in-php-and-mysql">handling dates and times with PHP and MySQL</a> .]]></description>
			<content:encoded><![CDATA[<p>Richard Lord wrote a good article explaining the various ways of <a href="http://www.bigroom.co.uk/blog/dates-in-php-and-mysql">handling dates and times with PHP and MySQL</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://iandunn.name/passing-dates-and-times-between-php-and-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

