<?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>MaisonBisson.com &#187; mysql</title>
	<atom:link href="http://maisonbisson.com/blog/post/tag/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://maisonbisson.com</link>
	<description>A bunch of stuff I would have emailed you about.</description>
	<lastBuildDate>Sat, 14 Nov 2009 20:14:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>The Difference Between MySQL&#8217;s utf8_unicode_ci and. utf8_general_ci Collations</title>
		<link>http://maisonbisson.com/blog/post/13859/the-difference-between-mysqls-utf8_unicode_ci-and-utf8_general_ci-collations/</link>
		<comments>http://maisonbisson.com/blog/post/13859/the-difference-between-mysqls-utf8_unicode_ci-and-utf8_general_ci-collations/#comments</comments>
		<pubDate>Mon, 11 May 2009 14:30:57 +0000</pubDate>
		<dc:creator>Casey</dc:creator>
				<category><![CDATA[Dispatches]]></category>
		<category><![CDATA[collation]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[utf8]]></category>
		<category><![CDATA[utf8_general_ci]]></category>
		<category><![CDATA[utf8_unicode_ci]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/?p=13859</guid>
		<description><![CDATA[
MySQL answer: utf8_unicode_ci vs. utf8_general_ci.
Collation controls sorting behavior. Unicode rationalizes the character set, but doesn&#8217;t, on it&#8217;s own, rationalize sorting behavior for all the various languages it supports. utf8_general_ci (ci = case insensitive) is apparently a bit faster, but sloppier, and only appropriate for English language data sets.
]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-13859"><!-- &nbsp; --></abbr>
<p>MySQL answer: <a title="Posteet: utf8_unicode_ci vs utf8_general_ci [charset] [collation] [interclassement] [mysql] [unicode] [utf8]" href="http://www.posteet.com/view/1340"><code>utf8_unicode_ci</code> vs. <code>utf8_general_ci</code></a>.</p>
<p><a title="Collation - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Collation">Collation</a> controls sorting behavior. Unicode rationalizes the character set, but doesn&#8217;t, on it&#8217;s own, rationalize sorting behavior for all the various languages it supports. <code>utf8_general_ci</code> (ci = case insensitive) is apparently a bit faster, but sloppier, and only appropriate for English language data sets.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/13859/the-difference-between-mysqls-utf8_unicode_ci-and-utf8_general_ci-collations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Slow Query Log Analysis</title>
		<link>http://maisonbisson.com/blog/post/13525/mysql-slow-query-log-analysis/</link>
		<comments>http://maisonbisson.com/blog/post/13525/mysql-slow-query-log-analysis/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 16:17:24 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Dispatches]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[slow query log]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/?p=13525</guid>
		<description><![CDATA[
Peter at MySQL Performance Blog pointed out this sweet perl script to analyze MySQL&#8217;s slow query logs. (This is supposedly a PHP port.)
The script does a good job of aggregating similar queries (those that only differ in their query values) and displaying overall stats for them. The following two queries are showing up a lot [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-13525"><!-- &nbsp; --></abbr>
<p>Peter at <a title="MySQL Performance Blog" href="http://www.mysqlperformanceblog.com/">MySQL Performance Blog</a> <a title="Slow Query Log analyzes tools | MySQL Performance Blog" href="http://www.mysqlperformanceblog.com/2006/09/06/slow-query-log-analyzes-tools/">pointed out</a> this <a title="http://www.mysqlperformanceblog.com/files/utils/mysql_slow_log_parser" href="http://www.mysqlperformanceblog.com/files/utils/mysql_slow_log_parser">sweet perl script</a> to analyze MySQL&#8217;s <a title="MySQL :: MySQL 5.0 Reference Manual :: 5.2.4 The Slow Query Log" href="http://dev.mysql.com/doc/refman/5.0/en/slow-query-log.html">slow query logs</a>. (<a title="mysql-log-filter - Google Code" href="http://code.google.com/p/mysql-log-filter/">This is supposedly a PHP port</a>.)</p>
<p>The script does a good job of aggregating similar queries (those that only differ in their query values) and displaying overall stats for them. The following two queries are showing up a lot in my WPMU installation because I also have it set to log queries that don&#8217;t use indexes. They&#8217;re not necessarily slow (MySQL &lt; 5.1 logs execution times to the nearest second, with a one second minimum), but the fact that they&#8217;re appearing a lot probably means the value isn&#8217;t being cached in Memcached.</p>
<p>The first SQL line shows the prototype for the query, the second is a real example from the log.</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">### 90379 Queries
### Total time: 90556, Average time: 1.00195841954436
### Taking 1  to 6  seconds to complete
### Rows analyzed 744 - 587874
SELECT COUNT(ID) FROM wp_XXX_posts WHERE post_status = 'XXX' and post_type = 'XXX';
&nbsp;
SELECT COUNT(ID) FROM wp_7_posts WHERE post_status = 'publish' and post_type = 'post';</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">### 8768 Queries
### Total time: 9033, Average time: 1.03022354014599
### Taking 1  to 4  seconds to complete
### Rows analyzed 0 - 199
SELECT option_name, option_value FROM wp_XXX_options FORCE INDEX(PRIMARY) ORDER BY option_id ASC;
&nbsp;
SELECT option_name, option_value FROM wp_4_options FORCE INDEX(PRIMARY) ORDER BY option_id ASC;</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/13525/mysql-slow-query-log-analysis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>5,848 (max), 656 (avg) MySQL Queries Per Second</title>
		<link>http://maisonbisson.com/blog/post/13456/5848-max-656-avg-mysql-queries-per-second/</link>
		<comments>http://maisonbisson.com/blog/post/13456/5848-max-656-avg-mysql-queries-per-second/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 05:00:33 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Dispatches]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[batcache]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[scriblio]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/?p=13456</guid>
		<description><![CDATA[

The above graph is far from typical, but I love that the box (the top one in this picture) can do the job when it needs to. This activity is a result of bulk record imports, web activity results in relatively little database traffic due to my use of Memcached and Batcache.
]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-13456"><!-- &nbsp; --></abbr>
<p><a title="5,848 (max), 656 (avg) MySQL Queries Per Second by misterbisson, on Flickr" href="http://www.flickr.com/photos/maisonbisson/3290635584/"><img src="http://farm4.static.flickr.com/3549/3290635584_af00ed2ef3.jpg" alt="5,848 (max), 656 (avg) MySQL Queries Per Second" width="500" height="72" /></a></p>
<p>The above graph is far from typical, but I love that the box (<a href="http://flickr.com/photos/scriblio/388446468/">the top one in this picture</a>) can do the job when it needs to. This activity is a result of bulk record imports, web activity results in relatively little database traffic due to my use of <a href="http://www.danga.com/memcached/">Memcached</a> and <a href="http://wordpress.org/extend/plugins/batcache/">Batcache</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/13456/5848-max-656-avg-mysql-queries-per-second/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oh Noes! My Table Is Gone!</title>
		<link>http://maisonbisson.com/blog/post/13203/oh-noes-my-table-is-gone/</link>
		<comments>http://maisonbisson.com/blog/post/13203/oh-noes-my-table-is-gone/#comments</comments>
		<pubDate>Tue, 20 Jan 2009 18:45:59 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Dispatches]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[fail]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysqlcheck]]></category>
		<category><![CDATA[optimize]]></category>
		<category><![CDATA[repair]]></category>
		<category><![CDATA[wp_options]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/?p=13203</guid>
		<description><![CDATA[
# mysqlcheck -p -A --auto-repair --optimize
wp_1_options
info     : Found block with too small length at 17732; Skipped
info     : Wrong block with wrong total length starting at 17776
info     : Found block with too small length at 28776; Skipped
warning  : Number of rows changed from [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-13203"><!-- &nbsp; --></abbr>
<pre># mysqlcheck -p -A --auto-repair --optimize
wp_1_options
info     : Found block with too small length at 17732; Skipped
info     : Wrong block with wrong total length starting at 17776
info     : Found block with too small length at 28776; Skipped
warning  : Number of rows changed from 444 to 441
status   : OK</pre>
<p>Cleaning up the mess after a hardware failure can suck. This mysqlcheck output is from the <code>wp_options</code> table for this blog. Unfortunately, if the <code>options</code> table is unreadable, all of WordPress panics and fails to load.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/13203/oh-noes-my-table-is-gone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL 5.1 Released, Community Takes Stock</title>
		<link>http://maisonbisson.com/blog/post/13196/mysql-51-released-community-takes-stock/</link>
		<comments>http://maisonbisson.com/blog/post/13196/mysql-51-released-community-takes-stock/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 15:53:18 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Dispatches]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[5.1]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[Drizzle]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[OurDelta]]></category>
		<category><![CDATA[quality]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/?p=13196</guid>
		<description><![CDATA[
MySQL 5.1 is out as a GA release, but with crashing bugs that should give likely users pause. Perhaps worse, the problems are blamed on essential breakdowns in the project management: “We have changed the release model so that instead of focusing on quality and features our release is now defined by timeliness and features. [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-13196"><!-- &nbsp; --></abbr>
<p><a href="http://www.mysql.com/products/enterprise/server.html" title="MySQL Enterprise Server 5.1">MySQL 5.1</a> is out as a <a href="http://dev.mysql.com/downloads/mysql/5.1.html" title="MySQL 5.1 Downloads — Generally Available (GA) release for production use">GA release</a>, but with <a href="http://monty-says.blogspot.com/2008/11/oops-we-did-it-again-mysql-51-released.html" title="Oops, we did it again (MySQL 5.1 released as GA with crashing bugs)">crashing bugs</a> that should give likely users pause. Perhaps worse, the problems are blamed on essential breakdowns in the project management: “We have changed the release model so that instead of focusing on quality and features our release is now defined by timeliness and features. Quality is not regarded to be that important.”</p>
<p>Still, <a href="http://jeremy.zawodny.com/blog/archives/010774.html" title="The New MySQL Landscape (by Jeremy Zawodny)">people are finding inspiration</a> in <a href="http://ourdelta.org/" title="OurDelta - Builds for MySQL">OurDelta</a> and <a href="https://launchpad.net/drizzle" title="A Lightweight SQL Database for Cloud and Web in Launchpad">Drizzle</a>. Competition from those braches/forks and criticism from the community are sure to help re-align the MySQL core, or provide a reasonable alternative if Sun/MySQL can&#8217;t deliver. In the meanwhile, the <a href="http://mysqlha.blogspot.com/" title="High Availability MySQL">High Availability MySQL</a> blog is worth following.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/13196/mysql-51-released-community-takes-stock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Converting MySQL Character Sets</title>
		<link>http://maisonbisson.com/blog/post/12619/converting-mysql-character-sets/</link>
		<comments>http://maisonbisson.com/blog/post/12619/converting-mysql-character-sets/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 16:17:51 +0000</pubDate>
		<dc:creator>Casey</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[character encoding]]></category>
		<category><![CDATA[character set]]></category>
		<category><![CDATA[character set conversion]]></category>
		<category><![CDATA[latin1]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/?p=12619</guid>
		<description><![CDATA[
This Gentoo Wiki page suggests dumping the table and using iconv to convert the characters, then insert the dump into a new table with the new charset.
Alex King solved a different problem: his apps were talking UTF8, but his tables were Latin1. His solution was to dump the tables, change the charset info in the [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12619"><!-- &nbsp; --></abbr>
<p>This <a title="TIP Convert latin1 to UTF-8 in MySQL - Gentoo Linux Wiki" href="http://gentoo-wiki.com/TIP_Convert_latin1_to_UTF-8_in_MySQL">Gentoo Wiki</a> page suggests dumping the table and using <a href="http://www.gnu.org/software/libiconv/documentation/libiconv/iconv.1.html">iconv</a> to convert the characters, then insert the dump into a new table with the new <a href="http://dev.mysql.com/doc/refman/5.1/en/charset.html">charset</a>.</p>
<p><a title="Fixing a MySQL Character Encoding Mismatch | alexking.org" href="http://alexking.org/blog/2008/03/06/mysql-latin1-utf8-conversion">Alex King solved a different problem</a>: his apps were talking UTF8, but his tables were Latin1. His solution was to dump the tables, change the charset info in the dump file, then re-insert the contents.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12619/converting-mysql-character-sets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Performance Monitoring Tips From The MySQL Newsletter</title>
		<link>http://maisonbisson.com/blog/post/12308/mysql-performance-monitoring-tips-from-the-mysql-newsletter/</link>
		<comments>http://maisonbisson.com/blog/post/12308/mysql-performance-monitoring-tips-from-the-mysql-newsletter/#comments</comments>
		<pubDate>Sun, 24 Aug 2008 15:57:52 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Dispatches]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/?p=12308</guid>
		<description><![CDATA[
Google turned this up, but i have no idea how old it is: How to Monitor MySQL&#8217;s performance.
]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12308"><!-- &nbsp; --></abbr>
<p>Google turned this up, but i have no idea how old it is: <a title="How to Monitor MySQL's performance" href="http://www.mysql.com/news-and-events/newsletter/2004-01/a0000000301.html">How to Monitor MySQL&#8217;s performance</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12308/mysql-performance-monitoring-tips-from-the-mysql-newsletter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Copying MySQL Usernames and Database Priveleges</title>
		<link>http://maisonbisson.com/blog/post/12205/copying-mysql-usernames-and-database-priveleges/</link>
		<comments>http://maisonbisson.com/blog/post/12205/copying-mysql-usernames-and-database-priveleges/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 19:51:37 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[copy users]]></category>
		<category><![CDATA[duplicate users]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysql users]]></category>
		<category><![CDATA[privileges]]></category>
		<category><![CDATA[users]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/?p=12205</guid>
		<description><![CDATA[
Now that I&#8217;m the nominal MySQL DBA for PSU, it became my job to jimmy up the MySQL user privileges so that the new web server could connect. I&#8217;m not sure if this is the fastest, most efficient way to do it, but it worked quickly enough:

CREATE TABLE mysql.user_copy SELECT * FROM mysql.user;
DELETE FROM mysql.user_copy [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12205"><!-- &nbsp; --></abbr>
<p>Now that I&#8217;m the nominal MySQL DBA for PSU, it became my job to jimmy up the MySQL user privileges so that the new web server could connect. I&#8217;m not sure if this is the fastest, most efficient way to do it, but it worked quickly enough:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">CREATE</span> <span style="color: #990099; font-weight: bold;">TABLE</span> mysql.user_copy <span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #CC0099;">*</span> <span style="color: #990099; font-weight: bold;">FROM</span> mysql.<span style="color: #000099;">user</span><span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">DELETE</span> <span style="color: #990099; font-weight: bold;">FROM</span> mysql.user_copy <span style="color: #990099; font-weight: bold;">WHERE</span> Host <span style="color: #CC0099; font-weight: bold;">NOT</span> <span style="color: #CC0099; font-weight: bold;">LIKE</span> <span style="color: #008000;">'OLD<span style="color: #008080; font-weight: bold;">_</span>HOST<span style="color: #008080; font-weight: bold;">_</span>NAME'</span><span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">UPDATE</span> mysql.user_copy <span style="color: #990099; font-weight: bold;">SET</span> Host <span style="color: #CC0099;">=</span> <span style="color: #008000;">'NEW<span style="color: #008080; font-weight: bold;">_</span>HOST<span style="color: #008080; font-weight: bold;">_</span>NAME'</span><span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">INSERT</span> <span style="color: #990099; font-weight: bold;">INTO</span> mysql.<span style="color: #000099;">user</span> <span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #CC0099;">*</span> <span style="color: #990099; font-weight: bold;">FROM</span> mysql.user_copy<span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">DROP</span> <span style="color: #990099; font-weight: bold;">TABLE</span> mysql.user_copy<span style="color: #000033;">;</span>
&nbsp;
<span style="color: #990099; font-weight: bold;">CREATE</span> <span style="color: #990099; font-weight: bold;">TABLE</span> mysql.db_copy <span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #CC0099;">*</span> <span style="color: #990099; font-weight: bold;">FROM</span> mysql.db<span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">DELETE</span> <span style="color: #990099; font-weight: bold;">FROM</span> mysql.db_copy <span style="color: #990099; font-weight: bold;">WHERE</span> Host <span style="color: #CC0099; font-weight: bold;">NOT</span> <span style="color: #CC0099; font-weight: bold;">LIKE</span> <span style="color: #008000;">'OLD<span style="color: #008080; font-weight: bold;">_</span>HOST<span style="color: #008080; font-weight: bold;">_</span>NAME'</span><span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">UPDATE</span> mysql.db_copy <span style="color: #990099; font-weight: bold;">SET</span> Host <span style="color: #CC0099;">=</span> <span style="color: #008000;">'NEW<span style="color: #008080; font-weight: bold;">_</span>HOST<span style="color: #008080; font-weight: bold;">_</span>NAME'</span><span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">INSERT</span> <span style="color: #990099; font-weight: bold;">INTO</span> mysql.db <span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #CC0099;">*</span> <span style="color: #990099; font-weight: bold;">FROM</span> mysql.db_copy<span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">DROP</span> <span style="color: #990099; font-weight: bold;">TABLE</span> mysql.db_copy<span style="color: #000033;">;</span>
&nbsp;
FLUSH <span style="color: #990099; font-weight: bold;">PRIVILEGES</span><span style="color: #000033;">;</span></pre></div></div>

<p>Simply replace the OLD_HOST_NAME and NEW_HOST_NAME with the appropriate values. Most importantly, I didn&#8217;t have to know the passwords for each user to do this. This script simply copied the user info and gave them access from the new server.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12205/copying-mysql-usernames-and-database-priveleges/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Optimizing Inserts/Updates On MySQL Tables</title>
		<link>http://maisonbisson.com/blog/post/12159/optimizing-insertsupdates-on-mysql-tables/</link>
		<comments>http://maisonbisson.com/blog/post/12159/optimizing-insertsupdates-on-mysql-tables/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 18:32:05 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[ALTER TABLE]]></category>
		<category><![CDATA[DISABLE KEYS]]></category>
		<category><![CDATA[ENABLE KEYS]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/?p=12159</guid>
		<description><![CDATA[
When doing a bulk insert/update/change to a MySQL table you can temporarily disable index updates like this:

ALTER TABLE $tbl_name DISABLE KEYS

&#8230;do stuff&#8230;

ALTER TABLE $tbl_name ENABLE KEYS

From the docs:
ALTER TABLE ... DISABLE KEYS tells MySQL to stop updating non-unique indexes. ALTER TABLE ... ENABLE KEYS then should be used to re-create missing indexes. MySQL does this [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12159"><!-- &nbsp; --></abbr>
<p>When doing a bulk insert/update/change to a MySQL table you can temporarily disable index updates like this:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">ALTER</span> <span style="color: #990099; font-weight: bold;">TABLE</span> $tbl_name <span style="color: #990099; font-weight: bold;">DISABLE</span> <span style="color: #990099; font-weight: bold;">KEYS</span></pre></div></div>

<p>&#8230;do stuff&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">ALTER</span> <span style="color: #990099; font-weight: bold;">TABLE</span> $tbl_name <span style="color: #990099; font-weight: bold;">ENABLE</span> <span style="color: #990099; font-weight: bold;">KEYS</span></pre></div></div>

<p>From <a href="http://dev.mysql.com/doc/refman/5.0/en/alter-table.html">the docs</a>:</p>
<blockquote><p><code>ALTER TABLE ... DISABLE KEYS</code> tells MySQL to stop updating non-unique indexes. <code>ALTER TABLE ... ENABLE KEYS</code> then should be used to re-create missing indexes. MySQL does this with a special algorithm that is much faster than inserting keys one by one, so disabling keys before performing bulk insert operations should give a considerable speedup. Using <code>ALTER TABLE ... DISABLE KEYS</code> requires the <code>INDEX</code> privilege in addition to the privileges mentioned earlier.<br />
While the non-unique indexes are disabled, they are ignored for statements such as <code>SELECT</code> and <code>EXPLAIN</code> that otherwise would use them.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12159/optimizing-insertsupdates-on-mysql-tables/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL Bug?</title>
		<link>http://maisonbisson.com/blog/post/12158/mysql-bug/</link>
		<comments>http://maisonbisson.com/blog/post/12158/mysql-bug/#comments</comments>
		<pubDate>Tue, 24 Jun 2008 19:13:49 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[GROUP BY]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[ORDER BY]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/?p=12158</guid>
		<description><![CDATA[
After an upgrade to MySQL 5.0.51b on RHEL 5 I started seeing curious results in a fairly common query. Here&#8217;s a simplified version:

SELECT ID, post_date_gmt 
FROM wp_posts
GROUP BY ID
ORDER BY post_date_gmt DESC 
LIMIT 5

What I expected was to get a handful of post ID numbers sorted in descending order by the post_date_gmt. Instead, I got [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12158"><!-- &nbsp; --></abbr>
<p>After an upgrade to MySQL 5.0.51b on RHEL 5 I started seeing curious results in a fairly common query. Here&#8217;s a simplified version:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">SELECT</span> ID<span style="color: #000033;">,</span> post_date_gmt 
<span style="color: #990099; font-weight: bold;">FROM</span> wp_posts
<span style="color: #990099; font-weight: bold;">GROUP BY</span> ID
<span style="color: #990099; font-weight: bold;">ORDER BY</span> post_date_gmt <span style="color: #990099; font-weight: bold;">DESC</span> 
<span style="color: #990099; font-weight: bold;">LIMIT</span> <span style="color: #008080;">5</span></pre></div></div>

<p>What I expected was to get a handful of post ID numbers sorted in descending order by the post_date_gmt. Instead, I got a list of post IDs sorted in ascending order by the ID number. Something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #cc66cc;">3</span>	<span style="color: #cc66cc;">2007</span><span style="color: #339933;">-</span><span style="color: #208080;">05</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">21</span> <span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span>
<span style="color: #cc66cc;">4</span>	<span style="color: #cc66cc;">2007</span><span style="color: #339933;">-</span><span style="color: #208080;">05</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">21</span> <span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span>
<span style="color: #cc66cc;">5</span>	<span style="color: #cc66cc;">2007</span><span style="color: #339933;">-</span><span style="color: #208080;">05</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">21</span> <span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span>
<span style="color: #cc66cc;">6</span>	<span style="color: #cc66cc;">2007</span><span style="color: #339933;">-</span><span style="color: #208080;">05</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">21</span> <span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span>
<span style="color: #cc66cc;">7</span>	<span style="color: #cc66cc;">2007</span><span style="color: #339933;">-</span><span style="color: #208080;">05</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">21</span> <span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span></pre></div></div>

<p>After some fiddling I discovered that the <code>GROUP BY</code> clause was causing a problem. So this query works:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">SELECT</span> ID<span style="color: #000033;">,</span> post_date_gmt 
<span style="color: #990099; font-weight: bold;">FROM</span> wp_posts
<span style="color: #990099; font-weight: bold;">ORDER BY</span> post_date_gmt <span style="color: #990099; font-weight: bold;">DESC</span> 
<span style="color: #990099; font-weight: bold;">LIMIT</span> <span style="color: #008080;">5</span></pre></div></div>

<p>&#8230;and outputs the results I expected:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #cc66cc;">337832</span>	<span style="color: #cc66cc;">2008</span><span style="color: #339933;">-</span><span style="color: #208080;">06</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">20</span> <span style="color: #cc66cc;">15</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">20</span><span style="color: #339933;">:</span><span style="color: #208080;">03</span>
<span style="color: #cc66cc;">335991</span>	<span style="color: #cc66cc;">2008</span><span style="color: #339933;">-</span><span style="color: #208080;">06</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">17</span> <span style="color: #cc66cc;">13</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">42</span>
<span style="color: #cc66cc;">337777</span>	<span style="color: #cc66cc;">2008</span><span style="color: #339933;">-</span><span style="color: #208080;">06</span><span style="color: #339933;">-</span><span style="color: #208080;">02</span> <span style="color: #cc66cc;">12</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">15</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">46</span>
<span style="color: #cc66cc;">337390</span>	<span style="color: #cc66cc;">2008</span><span style="color: #339933;">-</span><span style="color: #208080;">05</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">28</span> <span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span>
<span style="color: #cc66cc;">337831</span>	<span style="color: #cc66cc;">2008</span><span style="color: #339933;">-</span><span style="color: #208080;">05</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">28</span> <span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span><span style="color: #339933;">:</span><span style="color: #208080;">00</span></pre></div></div>

<p>The <code>GROUP BY</code> clause may be unnecessary, though it was originally written in to accommodate conditions where a <code>JOIN</code> (which is often added when the query is dynamically generated) causes MySQL to return multiple rows representing the same record ID.</p>
<p>Still, isn&#8217;t this behavior weird? It&#8217;s certainly different from previous versions.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12158/mysql-bug/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>.SHP to MySQL</title>
		<link>http://maisonbisson.com/blog/post/12154/shp-to-mysql/</link>
		<comments>http://maisonbisson.com/blog/post/12154/shp-to-mysql/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 23:21:51 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Dispatches]]></category>
		<category><![CDATA[.shp]]></category>
		<category><![CDATA[file conversion]]></category>
		<category><![CDATA[geodata]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[shp2mysql]]></category>
		<category><![CDATA[shp2mysql-php]]></category>
		<category><![CDATA[spatial data]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/?p=12154</guid>
		<description><![CDATA[
GIS data seems to come in .shp (shape?) files, but it&#8217;s not like MySQL knows what to do with those. this MySQL forum post points to a PHP tool and Windows executable that promise to convert the .shp data into something more useful to MySQL.
Superfluo explains a little more, and there&#8217;s lots of .shp data [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12154"><!-- &nbsp; --></abbr>
<p>GIS data seems to come in .shp (shape?) files, but it&#8217;s not like MySQL knows what to do with those. <a href="http://forums.mysql.com/read.php?23,122827,122827#msg-122827" title="MySQL :: Import SHP into MySQL.">this MySQL forum post</a> points to a <a href="http://sourceforge.net/projects/shp2mysql-php" title="SourceForge.net: SHP to MySQL in PHP">PHP tool</a> and <a href="http://kartoweb.itc.nl/RIMapper/" title="RIMapper and RIMapperWMS">Windows executable</a> that promise to convert the .shp data into something more useful to MySQL.</p>
<p><a href="http://superfluo.org/blojsom/blog/pic/geo/2007/11/13/Experimenting-with-MySQL-spatial-extensions.html" title="Superfluo">Superfluo</a> explains a little more, and there&#8217;s lots of .shp data to be had <a href="http://www.esri.com/data/download/census2000_tigerline/index.html" title="Census 2000 TIGER/Line Data">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12154/shp-to-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Find Stuff By Minimum Bounding Rectangle</title>
		<link>http://maisonbisson.com/blog/post/12148/find-stuff-by-minimum-bounding-rectangle/</link>
		<comments>http://maisonbisson.com/blog/post/12148/find-stuff-by-minimum-bounding-rectangle/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 19:34:31 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[MBR]]></category>
		<category><![CDATA[minimum bounding rectangle]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[MySQL spatial functions]]></category>
		<category><![CDATA[spatial data]]></category>
		<category><![CDATA[spatial functions]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/?p=12148</guid>
		<description><![CDATA[
MySQL offers ENVELOPE() to find the minimum bounding rectangle of a geometric object.
The result is a polygon with four segments, defined by five points. It took me a while to make sense of it, partially because the only documentation that I&#8217;ve run across so far for POLYGON() syntax is in the ENVELOPE() function mentioned above. [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12148"><!-- &nbsp; --></abbr>
<p><a href="http://www.flickr.com/photos/maisonbisson/2568621754/" title="mbr mysql minimum bounding rectangle by misterbisson, on Flickr"><img src="http://farm4.static.flickr.com/3276/2568621716_b5eb180c55_o.png" width="245" height="245" alt="mbr mysql minimum bounding rectangle" style="float: right;" /></a>MySQL offers <code>ENVELOPE()</code> to <a href="http://dev.mysql.com/doc/refman/5.0/en/general-geometry-property-functions.html#function_envelope" title="MySQL :: MySQL 5.0 Reference Manual :: 18.5.2.1 General Geometry Functions">find the minimum bounding rectangle</a> of a geometric object.</p>
<p>The result is a polygon with four segments, defined by five points. It took me a while to make sense of it, partially because the only documentation that I&#8217;ve run across so far for <code>POLYGON()</code> syntax is in the <code>ENVELOPE()</code> function mentioned above. I also had to draw a picture to think it through.</p>
<p>They write this: <code>POLYGON(( MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY ))</code>, I think this (in pseudocode-ish form): <code>POLYGON(( $point_a, $point_b, $point_c, $point_d, $point_a ))</code>, with the <code>$point_</code>s corresponding to the diagram.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12148/find-stuff-by-minimum-bounding-rectangle/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Working With Spatial Data in MySQL</title>
		<link>http://maisonbisson.com/blog/post/12147/working-with-spatial-data-in-mysql/</link>
		<comments>http://maisonbisson.com/blog/post/12147/working-with-spatial-data-in-mysql/#comments</comments>
		<pubDate>Thu, 12 Jun 2008 16:41:45 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[MySQL spatial functions]]></category>
		<category><![CDATA[spatial data]]></category>
		<category><![CDATA[spatial functions]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/?p=12147</guid>
		<description><![CDATA[
It&#8217;s MySQL spatial data week here, though I am spreading out the posts to, um, ease the pain (or boredom). Anyway, here are some commands/functions I don&#8217;t want to forget about later:
Start with an existing table called geometry, add a spatial column and index it:

ALTER TABLE geometry ADD coord POINT NOT NULL;
CREATE SPATIAL INDEX coord [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12147"><!-- &nbsp; --></abbr>
<p>It&#8217;s MySQL spatial data week here, though I am spreading out the posts to, um, ease the pain (or boredom). Anyway, here are some commands/functions I don&#8217;t want to forget about later:</p>
<p>Start with an existing table called <code>geometry</code>, add <a href="http://dev.mysql.com/doc/refman/5.0/en/creating-spatial-columns.html">a spatial column</a> and <a href="http://dev.mysql.com/doc/refman/5.0/en/creating-spatial-indexes.html">index it</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">ALTER</span> <span style="color: #990099; font-weight: bold;">TABLE</span> <span style="color: #999900; font-weight: bold;">geometry</span> <span style="color: #990099; font-weight: bold;">ADD</span> coord <span style="color: #999900; font-weight: bold;">POINT</span> <span style="color: #CC0099; font-weight: bold;">NOT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">CREATE</span> <span style="color: #FF9900; font-weight: bold;">SPATIAL</span> <span style="color: #990099; font-weight: bold;">INDEX</span> coord <span style="color: #990099; font-weight: bold;">ON</span> <span style="color: #999900; font-weight: bold;">geometry</span> <span style="color: #FF00FF;">&#40;</span>coord<span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">;</span></pre></div></div>

<p><a href="http://dev.mysql.com/doc/refman/5.0/en/populating-spatial-columns.html">Insert</a> some data; think in terms of POINT(X Y) or POINT(lat lon):</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">INSERT</span> <span style="color: #990099; font-weight: bold;">INTO</span> <span style="color: #999900; font-weight: bold;">geometry</span> <span style="color: #FF00FF;">&#40;</span>coord<span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">VALUES</span><span style="color: #FF00FF;">&#40;</span> <span style="color: #00CC00;">GeomFromText</span><span style="color: #FF00FF;">&#40;</span> <span style="color: #008000;">'POINT(40 -100)'</span> <span style="color: #FF00FF;">&#41;</span><span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">INSERT</span> <span style="color: #990099; font-weight: bold;">INTO</span> <span style="color: #999900; font-weight: bold;">geometry</span> <span style="color: #FF00FF;">&#40;</span>coord<span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">VALUES</span><span style="color: #FF00FF;">&#40;</span> <span style="color: #00CC00;">GeomFromText</span><span style="color: #FF00FF;">&#40;</span> <span style="color: #008000;">'POINT(1 1)'</span> <span style="color: #FF00FF;">&#41;</span><span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">;</span></pre></div></div>

<p>Get those <a href="http://dev.mysql.com/doc/refman/5.0/en/point-property-functions.html">X,Y coordinates</a> back from the table:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #00CC00;">X</span><span style="color: #FF00FF;">&#40;</span>coord<span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">,</span> <span style="color: #00CC00;">Y</span><span style="color: #FF00FF;">&#40;</span>coord<span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">FROM</span> <span style="color: #999900; font-weight: bold;">geometry</span></pre></div></div>

<p>Get points within a <a href="http://dev.mysql.com/doc/refman/5.0/en/relations-on-geometry-mbr.html" title="MySQL :: MySQL 5.0 Reference Manual :: 18.5.5 Relations on Geometry Minimal Bounding Rectangles (MBRs)">bounding rectangle</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #00CC00;">MBRContains</span><span style="color: #FF00FF;">&#40;</span>
	<span style="color: #00CC00;">GeomFromText</span><span style="color: #FF00FF;">&#40;</span> <span style="color: #008000;">'POLYGON((0 0,0 3,3 3,3 0,0 0))'</span> <span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">,</span>
	coord
<span style="color: #FF00FF;">&#41;</span>
<span style="color: #990099; font-weight: bold;">FROM</span> <span style="color: #999900; font-weight: bold;">geometry</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12147/working-with-spatial-data-in-mysql/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Calculating Distance Between Points In MySQL</title>
		<link>http://maisonbisson.com/blog/post/12146/calculating-distance-between-points-in-mysql/</link>
		<comments>http://maisonbisson.com/blog/post/12146/calculating-distance-between-points-in-mysql/#comments</comments>
		<pubDate>Wed, 11 Jun 2008 02:15:57 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[distance]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[MySQL spatial functions]]></category>
		<category><![CDATA[spatial functions]]></category>
		<category><![CDATA[unimplemented]]></category>
		<category><![CDATA[workaround]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/?p=12146</guid>
		<description><![CDATA[
MySQL has some powerful, and perhaps underused spatial extensions, but the most interesting functions are still unimplemented: “Note: Currently, MySQL does not implement these functions&#8230;”
Among those as-yet unimplemented functions is DISTANCE(). Alternatives can be found here and here, though neither is clean or simple. I wonder if a simple MBRContains() is good enough, though&#8230;
]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12146"><!-- &nbsp; --></abbr>
<p>MySQL has some powerful, and perhaps underused <a href="http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html" title="MySQL :: MySQL 5.0 Reference Manual :: 18 Spatial Extensions">spatial extensions</a>, but the <a href="http://dev.mysql.com/doc/refman/5.0/en/functions-that-test-spatial-relationships-between-geometries.html" title="MySQL :: MySQL 5.0 Reference Manual :: 18.5.6 Functions That Test Spatial Relationships Between Geometries">most interesting functions</a> are still <a href="http://maisonbisson.com/blog/post/12145/mysql-documentation">unimplemented</a>: “Note: Currently, MySQL does not implement these functions&#8230;”</p>
<p>Among those as-yet unimplemented functions is <code>DISTANCE()</code>. Alternatives can be found <a href="http://www.zcentric.com/blog/2007/03/calculate_distance_in_mysql_wi.html" title="Calculate Distance In Mysql with Latitude and Longitude (My Random Blog)">here</a> and <a href="http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL" title="Geo Distance Search with MySQL">here</a>, though neither is clean or simple. I wonder if a simple <a href="http://dev.mysql.com/doc/refman/5.0/en/relations-on-geometry-mbr.html"><code>MBRContains()</code></a> is good enough, though&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12146/calculating-distance-between-points-in-mysql/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL Documentation</title>
		<link>http://maisonbisson.com/blog/post/12145/mysql-documentation/</link>
		<comments>http://maisonbisson.com/blog/post/12145/mysql-documentation/#comments</comments>
		<pubDate>Mon, 09 Jun 2008 01:44:03 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Dispatches]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[funny]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[MySQL spatial functions]]></category>
		<category><![CDATA[spatial functions]]></category>
		<category><![CDATA[unimplemented]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/?p=12145</guid>
		<description><![CDATA[
Found in the MySQL 5.0 Reference Manual:

Related(g1,g2,pattern_matrix)
Returns 1 or 0 to indicate whether the spatial relationship specified by pattern_matrix exists between g1 and g2. Returns –1 if the arguments are NULL. The pattern matrix is a string. Its specification will be noted here if this function is implemented.

(emphasis mine.)
]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12145"><!-- &nbsp; --></abbr>
<p>Found in the <a href="http://dev.mysql.com/doc/refman/5.0/en/functions-that-test-spatial-relationships-between-geometries.html" title="MySQL :: MySQL 5.0 Reference Manual :: 18.5.6 Functions That Test Spatial Relationships Between Geometries">MySQL 5.0 Reference Manual</a>:</p>
<ul>
<li>Related(g1,g2,pattern_matrix)<br />
Returns 1 or 0 to indicate whether the spatial relationship specified by pattern_matrix exists between g1 and g2. Returns –1 if the arguments are NULL. The pattern matrix is a string. <strong>Its specification will be noted here if this function is implemented</strong>.</li>
</ul>
<p>(emphasis mine.)</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12145/mysql-documentation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL On Multi-Core Machines</title>
		<link>http://maisonbisson.com/blog/post/12086/mysql-on-multi-core-machines/</link>
		<comments>http://maisonbisson.com/blog/post/12086/mysql-on-multi-core-machines/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 12:11:17 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Dispatches]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[multi-core performance]]></category>
		<category><![CDATA[multiprocessing]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[table locking]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/post/12086/mysql-on-multi-core-or-machines</guid>
		<description><![CDATA[
The DevShed technical tour explains that MySQL can spawn new threads, each of which can execute on a different processor/core. What it doesn&#8217;t say is that a single thread can only execute on a single core, and if that thread locks a table, then no other threads that need that table can execute until the [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12086"><!-- &nbsp; --></abbr>
<p>The <a href="http://www.devshed.com/c/a/MySQL/A-Technical-Tour-of-MySQL/6/" title="Page 7 - A Technical Tour of MySQL">DevShed technical tour</a> explains that MySQL can spawn new threads, each of which can execute on a different processor/core. What it doesn&#8217;t say is that a single thread can only execute on a single core, and if that thread locks a table, then no other threads that need that table can execute until the locking thread/query is complete. Short answer: MySQL works well on multi-core machines until you lock a table.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12086/mysql-on-multi-core-machines/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache, MySQL, and PHP on MacOS X</title>
		<link>http://maisonbisson.com/blog/post/12075/apache-mysql-and-php-on-macos-x/</link>
		<comments>http://maisonbisson.com/blog/post/12075/apache-mysql-and-php-on-macos-x/#comments</comments>
		<pubDate>Thu, 24 Jan 2008 17:07:04 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[amp]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[installing]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[mac os X]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/post/12075/apache-mysql-and-php-on-macos-x</guid>
		<description><![CDATA[
p0ps Harlow tweeted something about trying to get an AMP environment running on his Mac. Conversation followed, and eventually I sent along an email that look sorta like this:
If you&#8217;re running 10.4 (I doubt it, but it&#8217;s worth mentioning because I&#8217;m most familiar with it), here&#8217;s how I&#8217;ve setup dozens of machines for web development [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12075"><!-- &nbsp; --></abbr>
<p><a href="http://www.p0ps.com/" title="p0ps.com">p0ps Harlow</a> tweeted something about trying to get an AMP environment running on his Mac. Conversation followed, and eventually I sent along an email that look sorta like this:</p>
<blockquote><p>If you&#8217;re running 10.4 (I doubt it, but it&#8217;s worth mentioning because I&#8217;m most familiar with it), here&#8217;s how I&#8217;ve setup dozens of machines for web development and WordPress:</p>
<p>Install MySQL<br />
<a href="http://dev.mysql.com/downloads/mysql/5.0.html#macosx-dmg">http://dev.mysql.com/downloads/mysql/5.0.html#macosx-dmg</a></p>
<p>Install Marc Liyanage&#8217;s PHP 5 package<br />
<a href="http://www.entropy.ch/software/macosx/php/">http://www.entropy.ch/software/macosx/php/</a></p>
<p>From there all you have to do is install WordPress.</p>
<p>10.5 changed lots of this (as you probably already know). The good news is that it includes current versions of the AMP suite. The bad news is that the PHP doesn&#8217;t include a number of useful components. Still, it will run WordPress and I&#8217;ve got it working on my laptop. These directions look like pretty much what I had to do:</p>
<p><a href="http://stringfoo.com/2007/11/05/server_setup_on_leopard/">http://stringfoo.com/2007/11/05/server_setup_on_leopard/</a><br />
<a href="http://remysharp.com/2007/10/27/lamp-in-leopard-osx-105-php5-and-apache-22">http://remysharp.com/2007/10/27/lamp-in-leopard-osx-105-php5-and-apache-22</a></p>
<p>It&#8217;s likely none of that will be helpful, in which case you will have discovered why I&#8217;m no longer a sysadmin.</p></blockquote>
<p><a href="http://www.entropy.ch/home/">Marc Liyanage</a>&#8217;s builds of <a href="http://www.entropy.ch/software/macosx/php/">PHP for Mac</a> are probably the easiest to use and they include most all the extensions a person could want, but he hadn&#8217;t released a package for Leopard at the time (<a href="http://www.entropy.ch/phpbb2/viewtopic.php?t=2945">he&#8217;s got a release in beta now</a>). As it turned out, p0ps actually was running 10.4, and he got things going in a jiffy.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12075/apache-mysql-and-php-on-macos-x/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WordPress to_ping Query Optimization</title>
		<link>http://maisonbisson.com/blog/post/12034/wordpress-to_ping-query-optimization/</link>
		<comments>http://maisonbisson.com/blog/post/12034/wordpress-to_ping-query-optimization/#comments</comments>
		<pubDate>Wed, 23 Jan 2008 17:34:26 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[fixed]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[query optimization]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/post/12034/wordpress-to_ping-query-optimization-2</guid>
		<description><![CDATA[
The WordPress team has taken up the issue of performance optimization pretty seriously, and I look forward to the fruits of their efforts, but I&#8217;m also casting a critical eye on my own code. Thanks to caching and a hugely optimized query architecture, Scriblio is now performing better than ever, and I&#8217;m now looking at [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12034"><!-- &nbsp; --></abbr>
<p>The WordPress team has taken up the issue of <a href="http://boren.nu/archives/2007/11/13/wordpress-24-performance-profiling/">performance optimization</a> pretty seriously, and I look forward to the fruits of their efforts, but I&#8217;m also casting a critical eye on my own code. Thanks to caching and a hugely optimized query architecture, Scriblio is now performing better than ever, and I&#8217;m now looking at the next tier of problems.</p>
<p>First among them is a WordPress query that runs to find which posts have pingbacks or trackbacks waiting to be processed. As it was originally written, it looked like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$trackbacks</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get_results</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;
	 SELECT ID 
	 FROM <span style="color: #006699; font-weight: bold;">$wpdb-&gt;posts</span> 
	 WHERE CHAR_LENGTH(TRIM(to_ping)) &gt; 7 
	 AND post_status = 'publish'
	&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The problem is that the query requires a full table scan, and it can&#8217;t be optimized simply by creating an index on <code>to_ping</code> because <code>CHAR_LENGTH(TRIM(to_ping)) > 7</code> requires inspecting every row and applying the functions before the result can be tested. As written, the query could take as long as 15 minutes to execute on a busy table of 350,000 rows.</p>
<p>Once I read through the code and determined that it&#8217;s very unlikely that cruft would be left in <code>to_ping</code>, or that any that was there would get removed once processed through the ping functions, I decided to try the query below. (Hat tip also to <a href="http://andy.wordpress.com/" title="Andy Skelton">Andy Skelton</a> for sanity checking my reading of the code.)</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$trackbacks</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get_results</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;
	 SELECT ID 
	 FROM <span style="color: #006699; font-weight: bold;">$wpdb-&gt;posts</span> 
	 WHERE to_ping &lt;&gt; '' 
	 AND post_status = 'publish'
	&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>A <a href="http://trac.wordpress.org/ticket/5649" title="#5649 (to_ping query optimization) - WordPress Trac - Trac">trac ticket</a> has been created and <a href="http://trac.wordpress.org/attachment/ticket/5649/comment_to_ping.diff" title="#5649: comment_to_ping.diff - WordPress Trac - Trac">patch added</a>, but despite the optimized query, a table as large as I&#8217;m working with probably needs an index to keep things running smoothly. So here&#8217;s what I&#8217;ve got:</p>
<p><code>KEY ping_status ( to_ping(1), post_status )</code></p>
<p>I&#8217;ve not yet confirmed that this is the most optimal index, but queries now take a fraction of a second to complete.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12034/wordpress-to_ping-query-optimization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress + Invalid URLs = Extra Database Queries</title>
		<link>http://maisonbisson.com/blog/post/12035/wordpress-invalid-urls-extra-database-queries/</link>
		<comments>http://maisonbisson.com/blog/post/12035/wordpress-invalid-urls-extra-database-queries/#comments</comments>
		<pubDate>Fri, 18 Jan 2008 13:38:13 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[404]]></category>
		<category><![CDATA[behavior]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[permalinks]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/post/12035/wordpress-invalid-urls-extra-database-queries</guid>
		<description><![CDATA[
After reporting weirdness last week I finally sat down with a completely clean and virgin install of WordPress 2.3.2 and traced what happens when you make a permalink request for a non-existent URL.
Here are two sets of URLs to use as examples and context:

These are valid URLs:

http://site.org/archives/101
http://site.org/page-name


These are _not_ valid URLs:

http://site.org/archivezorz/101
http://site.org/favicon.ico



Valid URLs get parsed, the [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12035"><!-- &nbsp; --></abbr>
<p>After <a href="http://comox.textdrive.com/pipermail/wp-hackers/2008-January/017144.html">reporting weirdness last week</a> I finally sat down with a completely clean and virgin install of WordPress 2.3.2 and traced what happens when you make a permalink request for a non-existent URL.</p>
<p>Here are two sets of URLs to use as examples and context:</p>
<ul>
<li>These are valid URLs:
<ul>
<li>http://site.org/archives/101</li>
<li>http://site.org/page-name</li>
</ul>
</li>
<li>These are _not_ valid URLs:
<ul>
<li>http://site.org/archivezorz/101</li>
<li>http://site.org/favicon.ico</li>
</ul>
</li>
</ul>
<p>Valid URLs get parsed, the expected MySQL queries get executed, and the results are processed and returned to the browser. Normal. The problem is that invalid URLs that get sent through WordPress still result in a query like the following being executed on the database. What?</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #990099; font-weight: bold;">SQL_CALC_FOUND_ROWS</span>  test_posts.<span style="color: #CC0099;">*</span> <span style="color: #990099; font-weight: bold;">FROM</span> test_posts  <span style="color: #990099; font-weight: bold;">WHERE</span> <span style="color: #008080;">1</span><span style="color: #CC0099;">=</span><span style="color: #008080;">1</span>  <span style="color: #CC0099; font-weight: bold;">AND</span> post_type <span style="color: #CC0099;">=</span> <span style="color: #008000;">'post'</span> <span style="color: #CC0099; font-weight: bold;">AND</span> <span style="color: #FF00FF;">&#40;</span>post_status <span style="color: #CC0099;">=</span> <span style="color: #008000;">'pub
lish'</span> <span style="color: #CC0099; font-weight: bold;">OR</span> post_status <span style="color: #CC0099;">=</span> <span style="color: #008000;">'private'</span><span style="color: #FF00FF;">&#41;</span>  <span style="color: #990099; font-weight: bold;">ORDER BY</span> post_date <span style="color: #990099; font-weight: bold;">DESC</span> <span style="color: #990099; font-weight: bold;">LIMIT</span> <span style="color: #008080;">0</span><span style="color: #000033;">,</span> <span style="color: #008080;">10</span></pre></div></div>

<p>That is, even after a URL is sent through <code>WP->parse_request()</code> and found to be invalid/404, WordPress marches on to <code>WP->query_posts()</code> and hits the database with a generic request for the X most recent posts. And because this is executed for every 404, it actually results in a lot of database activity.</p>
<p>In most cases MySQL has cached the result, and so it poses a minimal load on the server. And even if the cache is stale, for most sites it&#8217;s not a particularly resource intensive query.</p>
<p>But, if you&#8217;ve got <a href="http://library.plymouth.edu/browse/?subj=20th+century">350,000 rows in the posts table</a>, it&#8217;s incredibly resource intensive to order all those posts on the <code>post_date</code> (<code>datetime</code>) column. I&#8217;ve seen hundreds of them pile up and take <em>forever</em> to complete after writes to the table. It&#8217;s sufferable if write activity on the posts table is very low, but that&#8217;s not something I want to hope for.</p>
<p>So <a href="http://comox.textdrive.com/pipermail/wp-hackers/2008-January/017264.html">my question to the wp-hackers community</a> is: Do we actually want to execute that query for every 404 under normal circumstances? If not, is the following (or something like it) the stupidest solution?</p>
<p>In <a href="http://svn.automattic.com/wordpress/tags/2.3.2/wp-includes/classes.php">wp-includes/classes.php</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">	<span style="color: #000000; font-weight: bold;">function</span> query_posts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$wp_the_query</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">build_query_string</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// return if the request URI is a 404</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">did_permalink</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query_vars</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'error'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'404'</span> <span style="color: #009900;">&#41;</span>
			<span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000088;">$wp_the_query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query_vars</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The above works, but there&#8217;s probably a better way to write it.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12035/wordpress-invalid-urls-extra-database-queries/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bits Of MySQL Query Syntax I&#8217;ve Learned This Week</title>
		<link>http://maisonbisson.com/blog/post/12030/bits-of-mysql-query-syntax-ive-learned-this-week/</link>
		<comments>http://maisonbisson.com/blog/post/12030/bits-of-mysql-query-syntax-ive-learned-this-week/#comments</comments>
		<pubDate>Wed, 16 Jan 2008 17:23:09 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[join]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[queries]]></category>
		<category><![CDATA[subselect]]></category>
		<category><![CDATA[syntax]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/post/12030/bits-of-mysql-query-syntax-ive-learned-this-week</guid>
		<description><![CDATA[
Watching the WordPress hacker list this week, a couple messages related to selecting information about users schooled me on MySQL syntax. I obviously knew the following would work, but I&#8217;d previously used the UNION syntax in similar situations and somehow hadn&#8217;t thought of writing it this way:

SELECT
	&#40;SELECT meta_value FROM wp_usermeta WHERE meta_key = 'first_name' AND [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-12030"><!-- &nbsp; --></abbr>
<p>Watching the WordPress hacker list this week, a couple messages related to selecting information about users schooled me on MySQL syntax. I obviously knew the following would work, but I&#8217;d previously used the <code>UNION</code> syntax in similar situations and somehow hadn&#8217;t thought of writing it this way:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span>
	<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> meta_value <span style="color: #993333; font-weight: bold;">FROM</span> wp_usermeta <span style="color: #993333; font-weight: bold;">WHERE</span> meta_key <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'first_name'</span> <span style="color: #993333; font-weight: bold;">AND</span> user_id <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> first<span style="color: #66cc66;">,</span>
	<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> meta_value <span style="color: #993333; font-weight: bold;">FROM</span> wp_usermeta <span style="color: #993333; font-weight: bold;">WHERE</span> meta_key <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'last_name'</span> <span style="color: #993333; font-weight: bold;">AND</span> user_id <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> last<span style="color: #66cc66;">,</span>
	wp_users<span style="color: #66cc66;">.*</span>
<span style="color: #993333; font-weight: bold;">FROM</span>
	wp_users
<span style="color: #993333; font-weight: bold;">WHERE</span>
	wp_users<span style="color: #66cc66;">.</span>ID <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">2</span></pre></div></div>

<p>That&#8217;s much cleaner to my thinking, though I&#8217;ve no idea which is more optimal. When somebody replied asking for a solution that would work in pre-MySQL 5, this was the response:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> ID<span style="color: #66cc66;">,</span> user_login<span style="color: #66cc66;">,</span> first<span style="color: #66cc66;">.</span>meta_value <span style="color: #993333; font-weight: bold;">AS</span> fname<span style="color: #66cc66;">,</span> last<span style="color: #66cc66;">.</span>meta_value <span style="color: #993333; font-weight: bold;">AS</span> lname
<span style="color: #993333; font-weight: bold;">FROM</span> wp_users
<span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> wp_usermeta <span style="color: #993333; font-weight: bold;">AS</span> first <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #66cc66;">&#40;</span>wp_users<span style="color: #66cc66;">.</span>ID <span style="color: #66cc66;">=</span> first<span style="color: #66cc66;">.</span>user_id
<span style="color: #993333; font-weight: bold;">AND</span> first<span style="color: #66cc66;">.</span>meta_key <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'first_name'</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> wp_usermeta <span style="color: #993333; font-weight: bold;">AS</span> last <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #66cc66;">&#40;</span>wp_users<span style="color: #66cc66;">.</span>ID <span style="color: #66cc66;">=</span> last<span style="color: #66cc66;">.</span>user_id <span style="color: #993333; font-weight: bold;">AND</span> last<span style="color: #66cc66;">.</span>meta_key <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'last_name'</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>And the lesson to me here is that I didn&#8217;t realize the syntax allowed us to match multiple conditions for the <code>JOIN</code>. Makes sense, but I just hadn&#8217;t thought of it. Thanks go to Phil Williams and Otto for tipping me to these.</p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/12030/bits-of-mysql-query-syntax-ive-learned-this-week/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Freaking MySQL Character Set Encodings</title>
		<link>http://maisonbisson.com/blog/post/11972/freaking-mysql-character-set-encodings/</link>
		<comments>http://maisonbisson.com/blog/post/11972/freaking-mysql-character-set-encodings/#comments</comments>
		<pubDate>Mon, 05 Nov 2007 16:40:28 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[character set]]></category>
		<category><![CDATA[encoding]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[utf8 conversion]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/post/11972/freaking-mysql-character-set-encodings</guid>
		<description><![CDATA[
Derek Sivers&#8216; plan, with all it&#8217;s bin2hex and regexp and back and forth between MySQL and PHP almost looks good compared to what I&#8217;m about to do. Really, why is it so difficult to go from latin1 (tables created back in MySQL 3) to utf8? Not only do you have to set the charset on [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-11972"><!-- &nbsp; --></abbr>
<p><a href="http://www.oreillynet.com/onlamp/blog/2006/01/turning_mysql_data_in_latin1_t.html" title="Turning MySQL data in latin1 to utf8 utf-8 - O'Reilly ONLamp Blog">Derek Sivers</a>&#8216; plan, with all it&#8217;s bin2hex and regexp and back and forth between MySQL and PHP almost looks good compared to what I&#8217;m about to do. Really, why is it so difficult to go from latin1 (tables created back in MySQL 3) to utf8? Not only do you have to set the charset on <a href="http://dev.mysql.com/doc/refman/5.0/en/charset-syntax.html">the table</a>, but also <a href="http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html">the connection</a>, <a href="http://www.usphp.com/ini.core.html#ini.default-charset">in PHP</a>, and flipping everywhere. And then you&#8217;ve gotta deal with all this old data that&#8217;s in the wrong character set.</p>
<p>I got all excited when I learned of <a href="http://dev.mysql.com/doc/refman/5.0/en/charset-convert.html" title="MySQL AB :: MySQL 5.0 Reference Manual :: 9.7.2 CONVERT() and CAST()">CONVERT()</a> and <a href="http://dev.mysql.com/doc/refman/5.0/en/cast-functions.html">CAST()</a>, and felt completely betrayed when they turned out to be basically useless to me.</p>
<blockquote><p><code>CONVERT()</code> with <code>USING</code> is used to convert data between different character sets. In MySQL, transcoding names are the same as the corresponding character set names. For example, this statement converts the string <code>'abc'</code> in the default character set to the corresponding string in the <code>utf8</code> character set:</p>
<p><code>SELECT CONVERT('abc' USING utf8);</code></p></blockquote>
<p>Thing is, I can&#8217;t figure out where it&#8217;s inheriting “the default character set,” and I can&#8217;t seem to come up with a combination of settings that will do the job. <a href="http://www.phpwact.org/php/i18n/utf-8/mysql" title="MySQL and UTF-8 [Web Application Component Toolkit]">This old doc</a> looked promising at first, but quickly let me down.</p>
<p>Ack. It looks like I&#8217;m going to have to read the contents of a table using PHP and latin1 connection encoding, then insert the data into a duplicate table using utf8 connection encoding. Either that, or <a href="http://www.oreillynet.com/onlamp/blog/2006/01/turning_mysql_data_in_latin1_t.html">Derek Sivers&#8217; 28 step process</a>.</p>
<p>In the interest of documenting even the things that don&#8217;t work: I had high hopes for this, but it doesn&#8217;t do anything useful.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tables</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get_col</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'SHOW TABLES;'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// For every table in the database</span>
	<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tables</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$table</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$changes</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// create the new table, set it to UTF8</span>
		<span style="color: #000088;">$changes</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> “CREATE TABLE `conv_<span style="color: #000088;">$table</span>` LIKE `<span style="color: #000088;">$table</span>`”<span style="color: #339933;">;</span>
		<span style="color: #000088;">$changes</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> “ALTER TABLE `conv_<span style="color: #000088;">$table</span>` <span style="color: #b1b100;">DEFAULT</span> CHARACTER SET<span style="color: #339933;">=</span>utf8”<span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// copy the data into the new table, transcoding to UTF8</span>
		<span style="color: #000088;">$fields</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get_results</span><span style="color: #009900;">&#40;</span>“DESCRIBE <span style="color: #009900;">&#123;</span><span style="color: #000088;">$table</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>”<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>			
		<span style="color: #000088;">$allfields</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$selectfields</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fields</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$field</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$allfields</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$field</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Field</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$selectfields</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">stripos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$field</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Type</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'char'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #990000;">stripos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$field</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Type</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'text'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> ? “CONVERT<span style="color: #009900;">&#40;</span>`<span style="color: #000088;">$field</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Field</span>` USING utf8<span style="color: #009900;">&#41;</span>” <span style="color: #339933;">:</span> “`<span style="color: #000088;">$field</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Field</span>`”<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000088;">$changes</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> “INSERT INTO `conv_<span style="color: #000088;">$table</span>` <span style="color: #009900;">&#40;</span>`”<span style="color: #339933;">.</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$allfields</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'`, `'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span>“`<span style="color: #009900;">&#41;</span> SELECT ”<span style="color: #339933;">.</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$selectfields</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">', '</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span>“ FROM <span style="color: #000088;">$table</span>”<span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// move the old table aside and put the new one in place</span>
		<span style="color: #000088;">$changes</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> “<span style="color: #990000;">RENAME</span> TABLE `<span style="color: #000088;">$table</span>` TO `preutf8_<span style="color: #000088;">$table</span>`”<span style="color: #339933;">;</span>
		<span style="color: #000088;">$changes</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> “<span style="color: #990000;">RENAME</span> TABLE `conv_<span style="color: #000088;">$table</span>` TO `<span style="color: #000088;">$table</span>`”<span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// echo out the mysql commands</span>
		<span style="color: #b1b100;">echo</span> “<span style="color: #339933;">&lt;</span>h2 id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;11972_changes-to-table-tab_1&quot;</span> <span style="color: #339933;">&gt;</span>Changes to table <span style="color: #339933;">&lt;</span>code<span style="color: #339933;">&gt;</span><span style="color: #000088;">$table</span><span style="color: #339933;">&lt;/</span>code<span style="color: #339933;">&gt;:&lt;/</span>h2<span style="color: #339933;">&gt;</span>”<span style="color: #339933;">;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$changes</span><span style="color: #339933;">,</span> “<span style="color: #339933;">;&lt;</span>br <span style="color: #339933;">/&gt;</span>\n”<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><tags>mysql, character set, encoding, utf8 conversion</tags></p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/11972/freaking-mysql-character-set-encodings/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Installing MySQL with YUM</title>
		<link>http://maisonbisson.com/blog/post/11832/installing-mysql-with-yum/</link>
		<comments>http://maisonbisson.com/blog/post/11832/installing-mysql-with-yum/#comments</comments>
		<pubDate>Tue, 12 Jun 2007 20:14:52 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Blink]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[yellow dog updater modified]]></category>
		<category><![CDATA[yum]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/post/11832/#installing-mysql-with-yum</guid>
		<description><![CDATA[
how to install and configure MySQL database server
yum, mysql, linux, yellow dog updater modified
]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-11832"><!-- &nbsp; --></abbr>
<p><a href="http://www.epicdesigns.co.uk/howto/server_mysql.php" title="how to install and configure MySQL database server">how to install and configure MySQL database server</a></p>
<p><tags>yum, mysql, linux, yellow dog updater modified</tags></p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/11832/installing-mysql-with-yum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Easy MySQL Performance Tips</title>
		<link>http://maisonbisson.com/blog/post/11796/easy-mysql-performance-tips/</link>
		<comments>http://maisonbisson.com/blog/post/11796/easy-mysql-performance-tips/#comments</comments>
		<pubDate>Tue, 05 Jun 2007 15:19:14 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[query optimization]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/post/11796/#easy-mysql-performance-tips</guid>
		<description><![CDATA[
Yes, I&#8217;m still trying to squeeze more performance out of MySQL. And since small changes to a query can make a big difference in performance&#8230;
Here are two really easy things to be aware of:

Never do a COUNT(*) (or anything *, says Zach). Instead, replace the * with the name of the column you&#8217;re searching against [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-11796"><!-- &nbsp; --></abbr>
<p>Yes, I&#8217;m <a href="http://maisonbisson.com/blog/post/10970/">still trying</a> to squeeze more performance out of MySQL. And since small changes to a query can make a big difference in performance&#8230;</p>
<p>Here are two really easy things to be aware of:</p>
<ul>
<li><a href="http://www.mysqlperformanceblog.com/2007/04/10/count-vs-countcol/" title="MySQL Performance Blog » COUNT(*) vs COUNT(col)">Never do a <code>COUNT(*)</code></a> (or anything <code>*</code>, says <a href="http://nosheep.net/">Zach</a>). Instead, replace the <code>*</code> with the name of the column you&#8217;re searching against (and is hopefully indexed). That way some queries can execute entirely in the keycache (while * forces MySQL to read every matching row from the table).</li>
<li>When joining two large tables, but only searching against one, <a href="http://www.mysqlperformanceblog.com/2007/04/06/using-delayed-join-to-optimize-count-and-limit-queries/" title="MySQL Performance Blog » Using delayed JOIN to optimize count(*) and LIMIT queries">put the join statement at the end</a>. Why join the two entire tables when you only have to join the matching rows?</li>
</ul>
<p>I mention these because, well, I&#8217;ve known them forever, but upon seeing them again I realized I hadn&#8217;t really obeyed those simple rules in some of my queries.</p>
<p>Separately, there&#8217;s some pretty good info on <a href="http://www.mysqlperformanceblog.com/2006/06/08/mysql-server-variables-sql-layer-or-storage-engine-specific/" title="MySQL Performance Blog » MySQL Server Variables - SQL layer or Storage Engine specific.">what server variables affect what</a> at mysqlperformanceblog too.</p>
<p><tags>mysql, optimization, query optimization, performance, tips</tags></p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/11796/easy-mysql-performance-tips/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>MySQL Error 28: Temp Tables And Running Out of Disk Space</title>
		<link>http://maisonbisson.com/blog/post/11657/mysql-error-28-temp-tables-and-running-out-of-disk-space/</link>
		<comments>http://maisonbisson.com/blog/post/11657/mysql-error-28-temp-tables-and-running-out-of-disk-space/#comments</comments>
		<pubDate>Tue, 01 May 2007 23:32:33 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[disk space]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[error 28]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysql optimization]]></category>
		<category><![CDATA[query optimization]]></category>
		<category><![CDATA[table size]]></category>
		<category><![CDATA[temp table]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/post/11657/#mysql-error-28-temp-tables-and-running-out-of-disk-space</guid>
		<description><![CDATA[
Bam: MySQL error 28, and suddenly my queries came to a stop.
Error 28 is about disk space, usually the disk space for temp tables. The first thing to do is figure out what filesystem(s) the tables are on. SHOW VARIABLES LIKE “%dir%” will return a number of results, but the ones that matter are tmpdir [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-11657"><!-- &nbsp; --></abbr>
<p>Bam: <a href="http://www.mysql.com/news-and-events/newsletter/2003-10/a0000000249.html" title="MySQL AB :: Error 28, how to avoid it.">MySQL error 28</a>, and suddenly my queries came to a stop.</p>
<p>Error 28 is about disk space, usually the disk space for temp tables. The first thing to do is figure out what filesystem(s) the tables are on. <code>SHOW VARIABLES LIKE “%dir%”</code> will return a number of results, but the ones that matter are <code>tmpdir</code> and <code>datadir</code>.</p>
<p><code>SHOW VARIABLES LIKE “%dir%”;</p>
<p>basedir	/<br />
character_sets_dir	/usr/share/mysql/charsets/<br />
datadir	/var/lib/mysql/<br />
innodb_data_home_dir<br />
innodb_log_arch_dir<br />
innodb_log_group_home_dir	./<br />
innodb_max_dirty_pages_pct	90<br />
slave_load_tmpdir	/tmp/<br />
tmpdir	/tmp/</code></p>
<p>As it turns out, <code>df</code> shows plenty of space available on all the filesystems:</p>
<p><code># df -H<br />
Filesystem             Size   Used  Avail Use% Mounted on<br />
/dev/sda3              195G    11G   175G   6% /<br />
/dev/sda1               98M    16M    78M  17% /boot<br />
none                   1.1G      0   1.1G   0% /dev/shm<br />
/usr/tmpDSK            508M    12M   471M   3% /tmp<br />
/tmp                   508M    12M   471M   3% /var/tmp</code></p>
<p>Well, plenty of space if all it needs is 471MB of temp. Unfortunately, that&#8217;s not enough. The temp table is for a group/sort operation on a table that was much larger than I expected, something I realized when I looked at the table&#8217;s <code>Data_length</code> with <code>SHOW TABLE STATUS</code>.</p>
<p>I could change the temp directory, but unfortunately it <a href="http://dev.mysql.com/doc/refman/5.0/en/dynamic-system-variables.html" title="MySQL AB :: MySQL 5.0 Reference Manual :: 5.2.4.2 Dynamic System Variables">can&#8217;t be changed dynamically</a>, only at <a href="http://dev.mysql.com/doc/refman/5.0/en/program-variables.html" title="MySQL AB :: MySQL 5.0 Reference Manual :: 4.3.4 Using Options to Set Program Variables">startup</a>. So my choice was either to shutdown MySQL or change my query. As it turned out, it wasn&#8217;t a bad time to figure out how to write a better query.</p>
<p><tags>mysql, error 28, error, disk space, temp table, table size, query optimization, mysql optimization</tags></p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/11657/mysql-error-28-temp-tables-and-running-out-of-disk-space/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL Fulltext Tips</title>
		<link>http://maisonbisson.com/blog/post/11453/mysql-fulltext-tips/</link>
		<comments>http://maisonbisson.com/blog/post/11453/mysql-fulltext-tips/#comments</comments>
		<pubDate>Sun, 17 Sep 2006 16:09:29 +0000</pubDate>
		<dc:creator>Casey Bisson</dc:creator>
				<category><![CDATA[Blink]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[full text]]></category>
		<category><![CDATA[full text index]]></category>
		<category><![CDATA[keyword searching]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysql indexing]]></category>
		<category><![CDATA[Peter Gulutzan]]></category>
		<category><![CDATA[stopwords]]></category>

		<guid isPermaLink="false">http://maisonbisson.com/blog/post/11453/</guid>
		<description><![CDATA[
Peter Gulutzan, author of SQL Performance Tuning, writes in The Full-Text Stuff That We Didn&#8217;t Put In The Manual about the particulars of word boundaries, index structure, boolean searching, exact phrase searching, and stopwords, as well as offering a few articles for further reading (Ian Gilfillan&#8217;s “Using Fulltext Index in MySQL”, Sergei Golubchik&#8217;s “MySQL Fulltext [...]]]></description>
			<content:encoded><![CDATA[<abbr class="unapi-id" title="maisonbisson-11453"><!-- &nbsp; --></abbr>
<p><a href="http://www.oreillynet.com/pub/au/2059">Peter Gulutzan</a>, author of <a href="http://www.amazon.com/SQL-Performance-Tuning-Peter-Gulutzan/dp/0201791692?tag=maisonbisson-20/">SQL Performance Tuning</a>, writes in <a href="http://dev.mysql.com/tech-resources/articles/full-text-revealed.html" title="MySQL AB :: The Full-Text Stuff That We Didn't Put In The Manual">The Full-Text Stuff That We Didn&#8217;t Put In The Manual</a> about the particulars of word boundaries, index structure, boolean searching, exact phrase searching, and stopwords, as well as offering a few articles for further reading (Ian Gilfillan&#8217;s “<a href="http://www.databasejournal.com/features/mysql/article.php/1578331">Using Fulltext Index in MySQL</a>”, Sergei Golubchik&#8217;s “<a href="http://www.phpconference.de/2003/slides/database_track/golubchik_mysql_fulltext_search_2003.pdf">MySQL Fulltext Search</a>”, Joe Stump&#8217;s “<a href="http://www.onlamp.com/pub/a/onlamp/2003/06/26/fulltext.html">MySQL FULLTEXT Searching</a>”). It&#8217;s one of a number of <a href="http://dev.mysql.com/tech-resources/articles/" title="MySQL AB :: Articles about MySQL">articles</a> in the <a href="http://dev.mysql.com/tech-resources/" title="MySQL AB :: Tech Resources">MySQL Tech Resources</a> collection.</p>
<p><tags>mysql, full text, keyword searching, full text index, mysql indexing, stopwords, Peter Gulutzan</tags></p>
]]></content:encoded>
			<wfw:commentRss>http://maisonbisson.com/blog/post/11453/mysql-fulltext-tips/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>