<?xml version='1.0' encoding='utf-8' ?>
<!--  If you are running a bot please visit this policy page outlining rules you must respect. http://www.livejournal.com/bots/  -->
<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:media='http://search.yahoo.com/mrss/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>Morgan Tocker</title>
  <link>http://mtocker.livejournal.com/</link>
  <description>Morgan Tocker - LiveJournal.com</description>
  <lastBuildDate>Tue, 11 Aug 2009 18:57:40 GMT</lastBuildDate>
  <generator>LiveJournal / LiveJournal.com</generator>
  <lj:journal>mtocker</lj:journal>
  <lj:journalid>9433691</lj:journalid>
  <lj:journaltype>personal</lj:journaltype>
  <atom10:link rel='hub' href='http://pubsubhubbub.appspot.com/' />
  <image>
    <url>http://l-userpic.livejournal.com/49631266/9433691</url>
    <title>Morgan Tocker</title>
    <link>http://mtocker.livejournal.com/</link>
    <width>48</width>
    <height>48</height>
  </image>

<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/51318.html</guid>
  <pubDate>Tue, 11 Aug 2009 18:57:40 GMT</pubDate>
  <title>Analyzing Joyent&apos;s Accelerator for MySQL</title>
  <link>http://mtocker.livejournal.com/51318.html</link>
  <description>The Joyent Accelerator for MySQL is apparently 2-4 times faster than an EC2 instance, but there&apos;s no mention of configuration, database size or even what the queries were in their &lt;a href=&quot;http://www.mysql.com/news-and-events/generate-article.php?id=1625&quot;&gt;record breaking&lt;/a&gt; performance &lt;a href=&quot;http://www.joyent.com/products/publiccloud/virtual-appliances/mysql-accelerator/&quot;&gt;tests&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I assume that Joyent has tuned their MySQL install, so it only seems fair not to use the default configuration on the EC2 test.  If you look at &lt;a href=&quot;http://www.mysqlperformanceblog.com/2009/08/06/ec2ebs-single-and-raid-volumes-io-bencmark/&quot;&gt;Vadim&apos;s&lt;/a&gt; EBS benchmarks (particularly random read/write) it looks like they may have a very good product, but instead we&apos;re left with the impression that they have something to hide.&lt;br /&gt;&lt;br /&gt;1,245 transactions per second isn&apos;t very much these days if they are simple queries.  There are plenty of mysql installations doing ten times that.&lt;br /&gt;&lt;br /&gt;I&apos;ll update this post if they respond to me on twitter.  I&apos;d honestly like to dissect and look at what they&apos;re doing.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt; Joyent provided an &lt;a href=&quot;http://twitter.com/joyent/status/3251703288&quot;&gt;this&lt;/a&gt;:&lt;br /&gt;&lt;code&gt;@morgo watch for a blog post this week with the details. configurations and results of the internal test available now on the site #mysql&lt;/code&gt;</description>
  <comments>http://mtocker.livejournal.com/51318.html</comments>
  <category>mysql</category>
  <category>cloud</category>
  <category>joyent</category>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/50989.html</guid>
  <pubDate>Mon, 10 Aug 2009 15:20:52 GMT</pubDate>
  <title>Planet MySQL: What are you going to do with voting data?</title>
  <link>http://mtocker.livejournal.com/50989.html</link>
  <description>I&apos;m a fan of voting on planet mysql posts - but I&apos;ve also realized that since I&apos;m logged in, it allows someone to keep a pretty valuable silo of information on what interests me.  If I vote up a Kickfire or Infobright post, should I expect a sales call to follow?&lt;br /&gt;&lt;br /&gt;There&apos;s nothing in the &lt;a href=&quot;http://planet.mysql.com/faq&quot;&gt;FAQ&lt;/a&gt; about what happens with the data.</description>
  <comments>http://mtocker.livejournal.com/50989.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>22</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/50931.html</guid>
  <pubDate>Fri, 07 Aug 2009 18:22:23 GMT</pubDate>
  <title>Understanding the MySQL forks</title>
  <link>http://mtocker.livejournal.com/50931.html</link>
  <description>&lt;p&gt;I put together the following diagram to explain what the origin of the current MySQL forks and deltas looks like:&lt;/p&gt;

&lt;img src=&quot;http://tocker.id.au/files/mysql-forks.png&quot;&gt;

&lt;p&gt;But in the distributed revision control world we live in, it&apos;s never really that simple.  Here are
some other notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;XtraDB is an InnoDB fork and &quot;mostly&quot; only a storage engine.  It has a future in MariaDB
and Drizzle, but may not make it into MySQL (about to be owned by Oracle, who also owns InnoDB).&lt;/li&gt;

&lt;li&gt;OurDelta collects more patches than just the Percona patches, and enables the PBXT storage engine. There&apos;s also a repository of OurDelta for 5.1 - binaries just aren&apos;t out yet.&lt;/li&gt;

&lt;li&gt;Like XtraDB, PBXT has a future in Drizzle, MariaDB and *maybe* also MySQL (Oracle may be more
friendly towards PBXT than XtraDB, but Oracle is not known to be friendly so who knows!).
I left PBXT absent from the diagram for not having much of a lineage with previous MySQL releases (flames
welcome if you disagree).&lt;/li&gt;

&lt;li&gt;XtraDB draws a lot from the Google patches for MySQL/InnoDB (not present on the diagram either).&lt;/li&gt;

&lt;li&gt;Drizzle is now incompatible with everything else in MySQL-land terms
(replication, partitioning, etc),  and they&apos;re happy to be.  In storage engine terms,
they&apos;re still compatible though, which leads me to describe Drizzle as a completely new
&quot;userland&quot;, with storage engine options still remaining very similar.&lt;/li&gt;

&lt;li&gt;MariaDB is both a new storage engine (Maria) and a userland &quot;delta&quot; of MySQL.  I call it a delta
since it is trying to keep binary-format compatibility with MySQL wherever it can.  This means that
it makes a good retrofit, but it limits what they can do without changing things like the .frm format, etc.&lt;/li&gt;

&lt;li&gt;The InnoDB plugin has a weird history.  Oracle announced it as an optional replacement
for the 5.1 InnoDB but not much has become of it since introduction.  I would have expected
5.4 to be based off the plugin, but it&apos;s not (at least at this point).&lt;/li&gt;

&lt;li&gt;MySQL is the real loser in the direction the patches are moving.  While all other
forks are free to share amongst themselves (where compatible) and take from MySQL, MySQL will only 
accept a patch if the author signs a Contributor&apos;s License Agreement. They need to do this - otherwise 
they can&apos;t sell OEM copies, which still make a large chunk of sales.
Until recently, MySQL didn&apos;t accept any InnoDB patches unless they came downstream from Oracle, and
Oracle keeps InnoDB development as a closely guarded secret - which makes influencing it very difficult.&lt;/ul&gt;

&lt;p&gt;Comments welcome.&lt;/p&gt;</description>
  <comments>http://mtocker.livejournal.com/50931.html</comments>
  <category>mysql</category>
  <category>itsnotaforkitsaspoon</category>
  <lj:security>public</lj:security>
  <lj:reply-count>8</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/50441.html</guid>
  <pubDate>Fri, 05 Jun 2009 18:06:03 GMT</pubDate>
  <title>Hidden gems in 5.1</title>
  <link>http://mtocker.livejournal.com/50441.html</link>
  <description>I think 5.1 gets some &lt;a href=&quot;http://www.linux-mag.com/id/7342&quot;&gt;bad press&lt;/a&gt; for not being a compelling upgrade.  It&apos;s not the big features that make the difference, but the subtle ones.  I wanted to highlight some of the these that may make your life easier when it&apos;s time to upgrade:&lt;br /&gt;&lt;br /&gt;* Prepared statements can now use the query cache.  &lt;a href=&quot;http://bugs.mysql.com/bug.php?id=735&quot;&gt;BUG #735&lt;/a&gt;&lt;br /&gt;* InnoDB auto_increment insertion is more scalable.  &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html&quot;&gt;Manual Page&lt;/a&gt;&lt;br /&gt;* The long_query_time can be set to values less than 1 second. &lt;a href=&quot;http://bugs.mysql.com/bug.php?id=6238&quot;&gt;BUG #6238&lt;/a&gt;&lt;br /&gt;* &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/en/show-profiles.html&quot;&gt;SHOW PROFILES&lt;/a&gt; is available for everyone, not just community users!&lt;br /&gt;* Creating &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/en/create-trigger.html&quot;&gt;Triggers&lt;/a&gt; no longer requires the SUPER privilege.&lt;br /&gt;&lt;br /&gt;Let&apos;s hope for 1000 more of these in MySQL 5.4.</description>
  <comments>http://mtocker.livejournal.com/50441.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/50415.html</guid>
  <pubDate>Thu, 28 May 2009 20:14:20 GMT</pubDate>
  <title>Meetup.com can burn!</title>
  <link>http://mtocker.livejournal.com/50415.html</link>
  <description>In one week, the &lt;a href=&quot;http://planet.mysql.com/entry/?id=19240&quot;&gt;MySQL/Sun&lt;/a&gt; sponsored Meetup.com subscriptions expire officially.  While it&apos;s good to see that plenty of offers are available for sponsorship, I am kind of surprised that Meetup.com hasn&apos;t received much bad press out of this.&lt;br /&gt;&lt;br /&gt;To recap what happened:&lt;br /&gt;- (some years ago) Meetup.com introduced a great service for organizing meetups, and it was free!&lt;br /&gt;- Then they decided that they couldn&apos;t make money this way, so they switched to a paid-service-only model.&lt;br /&gt;- Most meetups on other topics started using things like &lt;a href=&quot;http://upcoming.yahoo.com/&quot;&gt;Upcoming&lt;/a&gt; and Facebook, but MySQL negotiated a deal to have all MySQL meetups sponsored.&lt;br /&gt;- Meetup.com decided they could make more money out of MySQL by charging for the groups individually, so they canceled the sponsorship deal.&lt;br /&gt;&lt;br /&gt;I&apos;m not against Meetup.com charging, but the way they&apos;ve essentially made a business is by &lt;a href=&quot;http://en.wikipedia.org/wiki/Bait_and_switch&quot;&gt;Bait and Switch&lt;/a&gt;.  I don&apos;t think we (as Open Source citizens) should encourage that, since one of the things we strive for is freedom from the vendor lock-in that makes this possible.</description>
  <comments>http://mtocker.livejournal.com/50415.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/49932.html</guid>
  <pubDate>Thu, 28 May 2009 14:03:12 GMT</pubDate>
  <title>Efficient way to copy large amounts of data?</title>
  <link>http://mtocker.livejournal.com/49932.html</link>
  <description>Dear Lazyweb,&lt;br /&gt;&lt;br /&gt;Yesterday I tried to Rsync a MySQL data directory from serverA to serverB on the same network.  I thought that if out of a few hunded gigabytes maybe 2% changed, this should work, right?  Wrong.  Rsync is designed to minimize bandwidth, so in my case it was *much* quicker to wipe the data and start again (I feel this is something I should have known earlier, but it doesn&apos;t hurt to try and share your mistakes).&lt;br /&gt;&lt;br /&gt;Which gets me thinking - it doesn&apos;t have to be this way.  Bit-torrent works in a similar way to Rsync, but it&apos;s certainly not network efficient.  Are there any projects similar to Rsync that are using network-hungry algorithms to try and make sure that two directories are in sync with the goal just being &lt;i&gt;as fast as possible&lt;/i&gt;?</description>
  <comments>http://mtocker.livejournal.com/49932.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>15</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/49748.html</guid>
  <pubDate>Mon, 27 Apr 2009 05:43:37 GMT</pubDate>
  <title>EC2 feature request: small instances that are 64-bit.</title>
  <link>http://mtocker.livejournal.com/49748.html</link>
  <description>I know it probably doesn&apos;t make sense to use 64-bit for instances with only 1300MB memory, but that&apos;s what I&apos;m asking.  The sooner we can just all use 64-bit, the easier it will be for management.</description>
  <comments>http://mtocker.livejournal.com/49748.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/49500.html</guid>
  <pubDate>Wed, 08 Apr 2009 19:25:23 GMT</pubDate>
  <title>Very Simple Introduction to Using XtraBackup on Max OS X</title>
  <link>http://mtocker.livejournal.com/49500.html</link>
  <description>I&apos;ve started using Xtrabackup to backup MySQL on my MacBook.  Here&apos;s an example of a quick backup and restore:&lt;br /&gt;&lt;br /&gt;1. Download the latest .tar.gz from Percona:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ cd /tmp&lt;br /&gt;$ wget &lt;a href=&quot;http://www.percona.com/mysql/xtrabackup/0.5/xtrabackup-0.5-macos.x86_64.tar.gz&quot;&gt;http://www.percona.com/mysql/xtrabackup/0.5/xtrabackup-0.5-macos.x86_64.tar.gz&lt;/a&gt;&lt;br /&gt;$ tar -xzf xtrabackup-*-macos.x86_64.tar.gz&lt;br /&gt;$ cd xtrabackup*&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;2. This directory should contain &lt;code&gt;innobackupex-1.5.1&lt;/code&gt; and &lt;code&gt;xtrabackup&lt;/code&gt;.  You need to install these into a directory that appears in your &lt;code&gt;$PATH&lt;/code&gt;.  In my case, I am going to group it install it where my MySQL binaries are located (/usr/local/mysql/bin):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ ls&lt;br /&gt;innobackupex-1.5.1      xtrabackup&lt;br /&gt;$ cp * /usr/local/mysql/bin/&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;3. Create a directory where you want your backup to go.  In this case it&apos;s just a demo - so I&apos;ll use my tmpdir.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ mkdir -p /tmp/backup&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;4. Test running the backup:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ innobackupex-1.5.1 /tmp/backup/&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;b&gt;Quick Explanation:&lt;/b&gt;&lt;br /&gt;&lt;code&gt;innobackupex-1.5.1&lt;/code&gt; is  a Perl script that insures that all of your non-InnoDB tables and other MySQL meta data is backed up.  You can think of it as a wrapper around &lt;code&gt;xtrabackup&lt;/code&gt;, which backs up the data inside InnoDB.&lt;br /&gt;&lt;br /&gt;5. Check the data is backed up:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ cd /tmp/backup&lt;br /&gt;$ ls&lt;br /&gt;2009-04-08_15-12-52&lt;br /&gt;$ cd 2009-04-08_15-12-52&lt;br /&gt;$ ls&lt;br /&gt;backup-my.cnf           mysql-stderr            xtrabackup_binlog_info&lt;br /&gt;employees               mysql-stdout            xtrabackup_checkpoints&lt;br /&gt;ibdata1                 test                    xtrabackup_logfile&lt;br /&gt;mysql&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;6. Attempt a recovery:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;innobackupex-1.5.1 --copy-back /tmp/backup/2009-04-08_15-12-52&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Disclaimer:&lt;/b&gt; In case you didn&apos;t know it, I work for Percona - the company that &lt;a href=&quot;http://www.mysqlperformanceblog.com/2009/04/07/xtrabackup-05-bugfixes-introduction-incremental-backup/&quot;&gt;wrote&lt;/a&gt; &lt;a href=&quot;http://www.percona.com/docs/wiki/percona-xtrabackup:start&quot;&gt;xtrabackup&lt;/a&gt;.</description>
  <comments>http://mtocker.livejournal.com/49500.html</comments>
  <category>mysql</category>
  <category>percona</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/49323.html</guid>
  <pubDate>Wed, 08 Apr 2009 18:31:32 GMT</pubDate>
  <title>Who is going to make MySQL easier to use?</title>
  <link>http://mtocker.livejournal.com/49323.html</link>
  <description>This may appear a bit of a rant - but it&apos;s really intended as more of an observation from having trained people how to use MySQL, and noticing that &lt;strong&gt;everyone seems to make the same beginner mistakes&lt;/strong&gt;.  If you read the &quot;&lt;a href=&quot;http://www.mysql.com/about/&quot;&gt;Continued MySQL Values&lt;/a&gt;&quot;  on the MySQL Website, you&apos;ll notice that the third one in the list is:
&lt;ul&gt;
&lt;li&gt;The best and the most-used database in the world for online applications&lt;/li&gt;
&lt;li&gt;Available and affordable for all&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easy to use&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Continuously improved while remaining fast, secure and reliable&lt;/li&gt;
&lt;li&gt;Fun to use and improve&lt;/li&gt;
&lt;li&gt;Free from bugs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;i&gt;&lt;strong&gt;Note&lt;/strong&gt; that &quot;Fun to use&quot; doesn&apos;t sound much like a database, and &quot;free from bugs&quot; will always be a distant dream ;)&lt;/i&gt;.&lt;/p&gt;

It was &lt;strong&gt;Easy to Use&lt;/strong&gt; that got me into MySQL, but I think this is one of the goals that has lost focus over the years.  If you look at &lt;a href=&quot;http://bugs.mysql.com/&quot;&gt;bugs.mysql.com&lt;/a&gt;, there are a lot of annoying little S5 (Feature Requests) that would probably take the right person only a few minutes to fix.  The sort of things I am talking about are:

&lt;ul&gt;
&lt;li&gt;SHOW SLAVE STATUS - Has at least one annoying ease of use bug.  If it refuses to connect to the master because it shares the same server id, it won&apos;t show you that here.  You have to go to the log file.&lt;/li&gt;
&lt;li&gt;SHOW SLAVE STATUS Also shows you the &apos;last error&apos; it incurred, with no way to clear this error.  It confuses beginners&lt;/li&gt;
&lt;li&gt;What is the difference between this wait_timeout and interactive_timeout thing, and why is it that when I set wait_timeout to 0 it converts to wait_timeout =1 and disconnects me? &lt;i&gt;- I would prefer wait_timeout=0 to mean unlimited - not that I can think of too many good reasons to use it.&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;The anonymous user serves almost no practical use.&lt;/li&gt;
&lt;li&gt;Changing InnoDB log file size requires you to do some shutdown and rename trickery, when this should be automatically done for you.&lt;/li&gt;
&lt;li&gt;When connecting to a server on -h localhost mysql decides that &quot;oh, you want the socket file&quot;, and due to misconfiguration it might go to the wrong location and tell you it can&apos;t connect even though your server is running.&lt;/li&gt;
&lt;li&gt;The error log file is very bad at offering levels of configurable verbosity, or consistency which would allow you to grep through it for errors easier.  Often it tells me an error code, which I am supposed to look up in perror - but most beginners don&apos;t know about perror.&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But they are probably never going to be fixed.  I think it is sad to see that many MySQL users have now seen that these issues don&apos;t get fixed, so they no longer submit feature request bug reports.  My theory is that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MySQL/Sun&lt;/strong&gt; is busy implementing new features to snag new customers.  If they update a feature (such as the subquery optimizations in 6.0) it is normally going to be one of those big compelling features that all of their customers are demanding.&lt;/li&gt;
&lt;li&gt;The small number of &lt;strong&gt;Community Contributors&lt;/strong&gt; are most likely going to be writing patches to scratch an itch (either better performance or diagnostics).  It&apos;s not going to be one of these annoying little things they long ago discovered and will no longer care about.&lt;/li&gt;
&lt;/ul&gt;

It&apos;s good to see that Drizzle has actually been very good at attacking a large number of items on my list.  It&apos;s just sad to have to wait until Drizzle is ready, because this part of MySQL isn&apos;t broken, it just &lt;i&gt;needs some love&lt;/i&gt;.</description>
  <comments>http://mtocker.livejournal.com/49323.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>5</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/49079.html</guid>
  <pubDate>Wed, 18 Mar 2009 13:52:59 GMT</pubDate>
  <title>New Amazon EC2 Features - Reserved Instances</title>
  <link>http://mtocker.livejournal.com/49079.html</link>
  <description>So you can now &lt;a href=&quot;http://aws.amazon.com/ec2/faqs/#What_is_a_Reserved_Instance&quot;&gt;reserve&lt;/a&gt; EC2 instances - which brings the cost down to about 6.7cents/hour averaged over a year.&lt;br /&gt;&lt;br /&gt;It&apos;s a great idea.  I wonder if the next step will be to allow more customized instance types at a price premium, provided a reservation is made for 1-3 years.  I could certainly use a machine with faster IO for MySQL boxes.</description>
  <comments>http://mtocker.livejournal.com/49079.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/48867.html</guid>
  <pubDate>Wed, 11 Feb 2009 22:46:28 GMT</pubDate>
  <title>I wish I had more levels of verbosity in logging</title>
  <link>http://mtocker.livejournal.com/48867.html</link>
  <description>&lt;p&gt;I&apos;ve been working as a Ruby on Rails developer the last couple of months.  It&apos;s interesting to see how my impression of MySQL changes when I&apos;m on the other side - and using a development environment I am less familiar with.  Here are a two things I wished I could have been able to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When &lt;code&gt;--log-warnings=2&lt;/code&gt; is enabled, log all statements the server receives that cause warnings or syntax errors.&lt;/li&gt;
&lt;li&gt;When &lt;code&gt;--log-warnings=2&lt;/code&gt; is enabled and &lt;code&gt;--some-other-setting&lt;/code&gt;, log all statements which return empty results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not that it caused me too much pain - but I think I could have benefited.  I think I&apos;ve read something about both of these before too... anyone know if it was in the Drizzle or Google patches?&lt;/p&gt;</description>
  <comments>http://mtocker.livejournal.com/48867.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/48442.html</guid>
  <pubDate>Fri, 30 Jan 2009 21:51:40 GMT</pubDate>
  <title>MySQL Consulting Companies</title>
  <link>http://mtocker.livejournal.com/48442.html</link>
  <description>Has anyone else noticed that almost all of the consulting companies that support MySQL (and blog) start with a &apos;P&apos;? (&lt;a href=&quot;http://www.percona.com/&quot;&gt;Percona&lt;/a&gt;, &lt;a href=&quot;http://www.pythian.com/&quot;&gt;Pythian&lt;/a&gt;, &lt;a href=&quot;http://www.provenscaling.com/&quot;&gt;Proven Scaling&lt;/a&gt;).  I think &lt;a href=&quot;http://www.openquery.com.au/&quot;&gt;OpenQuery&lt;/a&gt; needs a name change to keep up with the market.  Even though &apos;O&apos; is the letter next to &apos;P&apos; in the alphabet, it requires more than one bit flip - so it&apos;s not that close.</description>
  <comments>http://mtocker.livejournal.com/48442.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>8</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/48289.html</guid>
  <pubDate>Mon, 26 Jan 2009 00:08:21 GMT</pubDate>
  <title>My take on the Sun Database Group visa issues</title>
  <link>http://mtocker.livejournal.com/48289.html</link>
  <description>Seeing this &lt;a href=&quot;http://blogs.mysql.com/kaj/2009/01/12/on-open-source-and-open-competition-in-a-not-so-open-world/&quot;&gt;post&lt;/a&gt; make the news today really interested me - since I had the (dis)pleasure of being personally involved.  In the Australian spirit of &apos;giving word to the underdog&apos;, let me provide some clarity.  But before I do - my kudos to Kaj for already following up and correcting himself on the gray details.&lt;br /&gt;&lt;br /&gt;The person in question (&apos;KV&apos;) was not going to Australia to speak at a conference, but deliver a public training course.  To do this, you do need a business visa.  Heck, you need a visa if you want to teach in the USA - so those speculators calling Australia some draconian system that doesn&apos;t understand Open Source is just wrong.  &lt;a href=&quot;http://www.bom.gov.au&quot;&gt;Some&lt;/a&gt; &lt;a href=&quot;http://www.csiro.au/&quot;&gt;departments&lt;/a&gt; know it very well.  A &lt;a href=&quot;http://arstechnica.com/news.ars/post/20080829-open-source-group-sues-quebec-over-no-bid-microsoft-cotracts.html&quot;&gt;lot more&lt;/a&gt; than my adopted home of Quebec ;)&lt;br /&gt;&lt;br /&gt;The only advantage the USA has over Australia, is that speaking at conferences can be done with the VISA waiver system.  But then again, in Australia&apos;s defense the visas are acquired online, and much easier to acquire than my USA one was ;)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Why was local_mysql_activist upset?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;local_mysql_activist runs a business in Australia training on Open Source technologies.  On the same trip KV was due to teach in Sydney - KV was supposed to teach in Canberra.  And it was during that week in Canberra, local_mysql_activist had *already scheduled a class* that would no doubt compete for potential customers.&lt;br /&gt;&lt;br /&gt;But competition is good, no?  Well, yes.  But Sun can survive a lot longer on classes that only half fill than local_mysql_activist can.  In the spirit of healthy competition, they could have picked the week before/after - but that&apos;s their choice.  There are also other cities in Australia that come to mind before Canberra, which would have filled up.&lt;br /&gt;&lt;br /&gt;The real problem with the Sun/MySQL course is that it never actually ran.  It was canceled at the last minute due to low numbers, and customers were offered credits/refunds.  They probably didn&apos;t have enough time to book in to local_mysql_activist&apos;s class - so in the end he was the real loser.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The show did go on!&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;At the time I was also in the same training group at MySQL/Sun - and I happen to hold an Australian passport.  When KV was put-off by local_mysql_activist - the show still went on.  People in Australia still got their MySQL DBA course.  I think someone somewhere should acknowledge this bit in their stories.&lt;br /&gt;&lt;br /&gt;I don&apos;t support the way local_mysql_activist went about things.  &lt;a href=&quot;http://blogs.mysql.com/kaj/2009/01/12/on-open-source-and-open-competition-in-a-not-so-open-world/#comment-70278&quot;&gt;Involving&lt;/a&gt; a government is just a messy, messy, disaster.  But I can fully understand his frustrations.  What I would have done is capitalized on what MySQL&apos;s can&apos;t do - offer a completely reputable, third party criticism on which features work and which ones don&apos;t; i.e.&lt;br /&gt;&lt;br /&gt;Students used to ask me questions about what guides we had on migrating from Oracle to MySQL.  I used to tell them there was no really definitive guide, but if there was - don&apos;t you think we have a conflict of interest in producing it!?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Visa issues suck&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Visa issues suck.  I completely agree with Kaj on this one, having gone through both a Canadian and a USA visa myself.  Governments in general just don&apos;t know how to deal with the fact that you can be employed in a different country to where you work.&lt;br /&gt;&lt;br /&gt;Initially I was told by an immigration official that I wouldn&apos;t require a Canadian visa since my travel loosely met the definitions of a &apos;business traveler&apos; here on business from Australia, as long as I never received employment in Canada.&lt;br /&gt;&lt;br /&gt;That was until I came back in the country one day, and they detained me in immigration for a few hours, while they questioned me about my work - and eventually decided they were going to let me in, but I had 50 days to get a proper visa or get out.  I only just made it ;)&lt;br /&gt;&lt;br /&gt;[Disclaimer - I no longer work for Sun Microsystems.  If I wasn&apos;t so busy at my new job, I would have checked my RSS reader and replied earlier!]</description>
  <comments>http://mtocker.livejournal.com/48289.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/47930.html</guid>
  <pubDate>Wed, 24 Dec 2008 20:50:09 GMT</pubDate>
  <title>Heading to India</title>
  <link>http://mtocker.livejournal.com/47930.html</link>
  <description>I&apos;m about to leave for India for a few weeks - so if you&apos;re looking for me in Montreal - I won&apos;t be there.  What brings me there?  &lt;a href=&quot;http://rickshawrun.theadventurists.com/&quot;&gt;this.&lt;/a&gt;.</description>
  <comments>http://mtocker.livejournal.com/47930.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/47819.html</guid>
  <pubDate>Thu, 18 Dec 2008 14:24:14 GMT</pubDate>
  <title>IO scheduling in the 2.6 kernel</title>
  <link>http://mtocker.livejournal.com/47819.html</link>
  <description>I was surprised by even the gap I saw on Vadim&apos;s &lt;a href=&quot;http://www.mysqlperformanceblog.com/2008/12/18/xtradb-benchmarks-15x-gain/&quot;&gt;post&lt;/a&gt; on the improvements of using the Noop IO scheduler.  I&apos;ve been changing my thoughts on what to set the scheduler to lately, and it&apos;s all leaning to Noop as the default.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;An explanation first:&lt;/b&gt;&lt;br /&gt;IO Schedulers (aka elevators) are a method of trying to get the best possible performance out of your disk subsystem as possible.  Since your disk is essentially a mechanical device - it has a difference in performance between whether or not you are performing actions sequentially - or when you are performing actions randomly.  And this difference can be huge!  Last time I tested, a typical 7200RPM consumer hard drive could write 60MB/s sequentially, but performance dropped to only a few MB/s when I started trying to write small pieces of random data.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;So how do the IO schedulers work?&lt;/b&gt;&lt;br /&gt;They achieve this (mostly) by doing request reordering and merging, and by trying to read platters in one continuous direction.  They may even detect that you are writing sequential blocks, and slightly delay an operation in order to &apos;save cost&apos;.&lt;br /&gt;&lt;br /&gt;Each IO scheduler will have different algorithms regarding how they do this reordering.  For example, on a desktop Operating System you are probably more concerned about your MP3s not skipping than about the maximum sustained performance.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Death to schedulers&lt;/b&gt;&lt;br /&gt;The problem with using techniques like IO scheduling is that the Linux kernel is pretty dumb to all the layers below it.  Hard drives themselves have their own scheduling mechanisms, and if you are running a RAID controller *it* will have it&apos;s own scheduling mechanisms.&lt;br /&gt;&lt;br /&gt;The last point is important - If you are doing scheduling when you have a RAID controller, from Linux&apos;s perspective it&apos;s probably all one big block device.  The scheduler is making all sorts of assumptions about blocks being aligned on disk and it&apos;s WRONG WRONG WRONG - you probably have some sort of striping.  So all the IO scheduler is doing is adding latency (bad) and to probably applying some partial serialization to writes (double bad).&lt;br /&gt;&lt;br /&gt;So in that case, it&apos;s better to tell Linux to mind it&apos;s own business.  In which case you want the Noop scheduler.&lt;br /&gt;&lt;br /&gt;If you are curious where to learn more, I think the best references to learn more about scheduling have been some of the talks by the Youtube guys, and an earlier post by &lt;a href=&quot;http://dammit.lt/2008/02/05/linux-io-schedulers/&quot;&gt;Domas Mituzas&lt;/a&gt;.</description>
  <comments>http://mtocker.livejournal.com/47819.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>3</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/47372.html</guid>
  <pubDate>Wed, 17 Dec 2008 18:17:29 GMT</pubDate>
  <title>Why you don&apos;t want to work in a travel job for Sun</title>
  <link>http://mtocker.livejournal.com/47372.html</link>
  <description>I left Sun over a month ago.  Despite my manager approving my expense report, the accounting team has refused it.  Now I&apos;m supposed to pay a $6,000 Amex bill while I wait for them to figure out what they are going to do.</description>
  <comments>http://mtocker.livejournal.com/47372.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/47160.html</guid>
  <pubDate>Wed, 10 Dec 2008 15:49:44 GMT</pubDate>
  <title>On Synergy: Culture conflicts between Sun and MySQL</title>
  <link>http://mtocker.livejournal.com/47160.html</link>
  <description>Working at Sun was my first acquisition experience.  I guess it was what I expected; managers hyping it up about being a &quot;perfect match&quot;, and how much the two companies had in common.  It was kind of interesting to see this even turned up a notch after they received additional &quot;Sun management training&quot;.  Anyway, I digress....&lt;br /&gt;&lt;br /&gt;I&apos;ll state upfront I consider my experience a bad one (but I&apos;ll save the personal stories for another day).  Here was an issue I saw while training Sun staff on how to user MySQL:&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Sun&apos;s has a conflict of interest in selling hardware.&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;MySQL (InnoDB) doesn&apos;t actually *work* on big computers.  It only scales up to about 4-8 CPU cores, and then it hits all sorts of internal bottlenecks.  Most architectures work around this by using many small machines rather than one big one (aka &quot;scale out&quot;).&lt;br /&gt;&lt;br /&gt;But for Sun the profits are larger on selling *bigger* hardware.  Most of Sun&apos;s bigger hardware (SPARC) has many more CPU cores, but each of these cores are infact slower than most Intel/AMD cores.  So it doesn&apos;t work.&lt;br /&gt;&lt;br /&gt;I&apos;m not sure that the &quot;old guard&quot; of Sun Sales people will take to selling smaller, lower margin systems.  I can predict them still trying to continue to either sell bigger machines (and suggest deploying Oracle), or sell bigger machines that are actually unsuited to MySQL[1].  I remember hearing a Clayton Christensen talk on when Intel launched Celeron - and they sold them out of a completely different office.  That sounded smart.&lt;br /&gt;&lt;br /&gt;I think the idea of using commodity hardware installing DRBD+Heartbeat was the hardest to explain to Sun employees in HA classes.  They didn&apos;t see why someone wouldn&apos;t buy a $5,000-$10,000 SAN and be done with it (Note: I should point out DRBD has other advantages besides being a low-cost SAN replacement).&lt;br /&gt;&lt;br /&gt;[1] &lt;a href=&quot;http://blogs.sun.com/mrbenchmark/entry/scaling_mysql_on_a_256&quot;&gt;This review&lt;/a&gt; is just one example.  The &lt;a href=&quot;http://www.mysqlperformanceblog.com/2008/11/11/scaling-to-256-way-the-sun-way/&quot;&gt;analysis&lt;/a&gt; is even more interesting.</description>
  <comments>http://mtocker.livejournal.com/47160.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>19</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/46888.html</guid>
  <pubDate>Wed, 10 Dec 2008 15:02:33 GMT</pubDate>
  <title>Eating your own dog food.</title>
  <link>http://mtocker.livejournal.com/46888.html</link>
  <description>I&apos;m pretty happy to hear that the MySQL Website, and the MySQL Bugs system are powered by 5.1.  I think this is a real step forward from when 5.0 was released.&lt;br /&gt;&lt;br /&gt;I just want to know when the support.mysql.com website will use 5.1.  It has a lot heavier requirements, and with contracted SLAs to customers Sun would be making a real commitment if it were to upgrade that.</description>
  <comments>http://mtocker.livejournal.com/46888.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/46707.html</guid>
  <pubDate>Fri, 28 Nov 2008 19:56:00 GMT</pubDate>
  <title>There&apos;s nothing point one about 5.1</title>
  <link>http://mtocker.livejournal.com/46707.html</link>
  <description>MySQL 5.1 is GA.  Yay!&lt;br /&gt;&lt;br /&gt;A lot of new features have been added, and the numbering convention of just adding a .1 doesn&apos;t really explain that.  If I had of numbered it, I probably would have called it &quot;6.0&quot;.&lt;br /&gt;&lt;br /&gt;In some ways MySQL has done both themselves (and DBAs) a small injustice.  While working at MySQL I met a lot of customers that tended to be conservative - they don&apos;t install first releases, but instead wait for the second release[1].&lt;br /&gt;&lt;br /&gt;In the case of 5.1, just be aware that there will be quite a few more features, and with it &lt;b&gt;will be&lt;/b&gt; more bugs.  I think it&apos;s more stable than 5.0 - but you will still need to do plenty of testing.&lt;br /&gt;&lt;br /&gt;I&apos;m happy to see it finally released though - 3 years in the making!&lt;br /&gt;&lt;br /&gt;But again if I had it my way, it would have been good to see a real &quot;Point 1&quot; release to 5.0.  There were a lot of new features introduced in late 2005 that only required small addition.  Changes that were large enough that the current &apos;no new features in a GA release&apos; rule restricted, but not big enough to break 99% of applications[2].&lt;br /&gt;&lt;br /&gt;I can only hope that 6.0 is 5.1&apos;s &quot;point 1 release&quot;, and not just a deluge of new features 2 years late.  Partitioning could be awesome if things like the &quot;can&apos;t mix storage engine&quot; limitation were lifted.  Quickly.&lt;br /&gt;&lt;br /&gt;I probably will be waiting at least until &lt;a href=&quot;http://www.percona.com/percona-lab.html&quot;&gt;Percona&lt;/a&gt; and &lt;a href=&quot;http://www.ourdelta.org/&quot;&gt;OurDelta&lt;/a&gt; update to 5.1 GA, and perhaps another month after that.&lt;br /&gt;&lt;br /&gt;[1] I think Oracle causes this - having traditionally offered much stronger second editions.&lt;br /&gt;[2] For example; I now don&apos;t have to use the SUPER privilege for triggers, but I still have no way of using SIGNAL in a stored procedure.  It&apos;s a shame that for both of these the compile cache is still per-connection.</description>
  <comments>http://mtocker.livejournal.com/46707.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/46579.html</guid>
  <pubDate>Mon, 24 Nov 2008 18:45:07 GMT</pubDate>
  <title>Dead-simple server monitoring solutions</title>
  <link>http://mtocker.livejournal.com/46579.html</link>
  <description>Dear Lazyweb.  So, here&apos;s my thoughts:&lt;br /&gt;&lt;br /&gt;* Create a basic php/rails/insert your application language choice page.&lt;br /&gt;* Have it do a simple SELECT 1+1 from MySQL.&lt;br /&gt;* Print the results to screen.&lt;br /&gt;&lt;br /&gt;Are there any third party (independently hosted) monitoring tools out there that (for free or cheap) I can use to then connect to this page, and make sure the results are as expected?</description>
  <comments>http://mtocker.livejournal.com/46579.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/46316.html</guid>
  <pubDate>Fri, 14 Nov 2008 14:44:48 GMT</pubDate>
  <title>Today is my last day at Sun</title>
  <link>http://mtocker.livejournal.com/46316.html</link>
  <description>After almost 3 years working in Support then Training, it&apos;s time to move on.  I haven&apos;t blogged much in a while, but it&apos;s something I plan to work on more now I sit on the other side.</description>
  <comments>http://mtocker.livejournal.com/46316.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>3</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/46002.html</guid>
  <pubDate>Thu, 23 Oct 2008 17:50:39 GMT</pubDate>
  <title>Montreal on Rails</title>
  <link>http://mtocker.livejournal.com/46002.html</link>
  <description>I spoke at Montreal on Rails on Tuesday night.  I think I had 5 slides, but spoke for about 45 minutes (so there&apos;s no point in uploading them).  For those that missed it (or couldn&apos;t take notes fast enough), here&apos;s a transcript of the examples I showed with the &lt;a href=&quot;http://dev.mysql.com/doc&quot;&gt;world database&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
# take a look at this query.  To start with, we have no indexes used:
EXPLAIN SELECT Name FROM Country WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 5000000 ORDER BY Name;

# First let&apos;s look at an index on population
ALTER TABLE Country ADD INDEX p (Population);

# is that index effective?
EXPLAIN SELECT Name FROM Country WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 5000000 ORDER BY Name;

# no it wasn&apos;t.  what happens if we modify the query just slightly:
EXPLAIN SELECT Name FROM Country WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 50000000 ORDER BY Name;

# time for the next index:
ALTER TABLE Country ADD INDEX c (Continent);

# with two indexes on the table, which one will the optimizer prefer?
EXPLAIN SELECT Name FROM Country WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 50000000 ORDER BY Name;

# how about now?
EXPLAIN SELECT Name FROM Country WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 500000000 ORDER BY Name;

# This index is not always helpful.  Why?
ALTER TABLE Country ADD INDEX p_c (Population, Continent);

# How about this one?
ALTER TABLE Country ADD INDEX c_p (Continent,Population);

# Why is this one better than just c_p?
ALTER TABLE Country ADD INDEX c_p_n (Continent,Population,Name);

# Remote all the indexes before trying to add an index on n.
ALTER TABLE Country DROP INDEX p, DROP INDEX c, DROP INDEX p_c, DROP INDEX c_p, DROP INDEX c_p_n;
ALTER TABLE Country ADD INDEX n (Name);

# the optimizer still doesn&apos;t consider N.
EXPLAIN SELECT Name FROM Country WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 500000000 ORDER BY Name;

# how about now?
EXPLAIN SELECT Name FROM Country FORCE INDEX (n) WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 500000000 ORDER BY Name;

# drop the index on N.
alter table Country drop index n;


# SOME trick questions
# which is better.

EXPLAIN SELECT * FROM City WHERE id = 1810;
EXPLAIN SELECT * FROM City WHERE id = 1810 LIMIT 1;

# How about this one.

EXPLAIN SELECT * FROM City WHERE id BETWEEN 100 and 200;
EXPLAIN SELECT * FROM City WHERE id &amp;gt;= 100 and id &amp;lt;= 200;

# (the answer is that both of the two above are identical - 
#  they are rewritten internally to the same thing)

# This is a bad subquery.
EXPLAIN SELECT * FROM City WHERE countrycode IN (SELECT code FROM country WHERE name=&apos;Australia&apos;)

# this is the rewrite as a join.
EXPLAIN SELECT city.* FROM City, Country WHERE city.countrycode=country.code AND country.name=&apos;Australia&apos;

# does this index help?
ALTER TABLE City ADD INDEX (countrycode);

# retry
EXPLAIN SELECT city.* FROM City, Country WHERE city.countrycode=country.code AND country.name=&apos;Australia&apos;;

# add an index on city.
ALTER TABLE Country ADD INDEX (name);

# how about a retry
EXPLAIN SELECT city.* FROM City, Country WHERE city.countrycode=country.code AND country.name=&apos;Australia&apos;;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Pretty neat, huh?  I teach something similar in DBA classes.  I have to thank &lt;a href=&quot;http://www.flupps.org/&quot;&gt;Tobias&lt;/a&gt; for first showing me a fair chunk of this example.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt;  Transcript of output:&lt;br /&gt;&lt;pre&gt;
mysql&amp;gt; EXPLAIN SELECT Name FROM Country WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 5000000 ORDER BY Name;
+----+-------------+---------+------+---------------+------+---------+------+------+-----------------------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra                       |
+----+-------------+---------+------+---------------+------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | Country | ALL  | NULL          | NULL | NULL    | NULL |  239 | Using where; Using filesort | 
+----+-------------+---------+------+---------------+------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)

mysql&amp;gt; ALTER TABLE Country ADD INDEX p (Population);
Query OK, 239 rows affected (0.01 sec)
Records: 239  Duplicates: 0  Warnings: 0

mysql&amp;gt; EXPLAIN SELECT Name FROM Country WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 5000000 ORDER BY Name;
+----+-------------+---------+------+---------------+------+---------+------+------+-----------------------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra                       |
+----+-------------+---------+------+---------------+------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | Country | ALL  | p             | NULL | NULL    | NULL |  239 | Using where; Using filesort | 
+----+-------------+---------+------+---------------+------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)

mysql&amp;gt; EXPLAIN SELECT Name FROM Country WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 50000000 ORDER BY Name;
+----+-------------+---------+-------+---------------+------+---------+------+------+-----------------------------+
| id | select_type | table   | type  | possible_keys | key  | key_len | ref  | rows | Extra                       |
+----+-------------+---------+-------+---------------+------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | Country | range | p             | p    | 4       | NULL |   54 | Using where; Using filesort | 
+----+-------------+---------+-------+---------------+------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)

mysql&amp;gt; ALTER TABLE Country ADD INDEX c (Continent);
Query OK, 239 rows affected (0.00 sec)
Records: 239  Duplicates: 0  Warnings: 0

mysql&amp;gt; EXPLAIN SELECT Name FROM Country WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 50000000 ORDER BY Name;
+----+-------------+---------+------+---------------+------+---------+-------+------+-----------------------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref   | rows | Extra                       |
+----+-------------+---------+------+---------------+------+---------+-------+------+-----------------------------+
|  1 | SIMPLE      | Country | ref  | p,c           | c    | 1       | const |   42 | Using where; Using filesort | 
+----+-------------+---------+------+---------------+------+---------+-------+------+-----------------------------+
1 row in set (0.00 sec)

mysql&amp;gt; EXPLAIN SELECT Name FROM Country WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 500000000 ORDER BY Name;
+----+-------------+---------+-------+---------------+------+---------+------+------+-----------------------------+
| id | select_type | table   | type  | possible_keys | key  | key_len | ref  | rows | Extra                       |
+----+-------------+---------+-------+---------------+------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | Country | range | p,c           | p    | 4       | NULL |    4 | Using where; Using filesort | 
+----+-------------+---------+-------+---------------+------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)

mysql&amp;gt; ALTER TABLE Country ADD INDEX p_c (Population, Continent);
Query OK, 239 rows affected (0.00 sec)
Records: 239  Duplicates: 0  Warnings: 0

mysql&amp;gt; ALTER TABLE Country ADD INDEX c_p (Continent,Population);
Query OK, 239 rows affected (0.00 sec)
Records: 239  Duplicates: 0  Warnings: 0

mysql&amp;gt; ALTER TABLE Country ADD INDEX c_p_n (Continent,Population,Name);
Query OK, 239 rows affected (0.01 sec)
Records: 239  Duplicates: 0  Warnings: 0

mysql&amp;gt; ALTER TABLE Country DROP INDEX p, DROP INDEX c, DROP INDEX p_c, DROP INDEX c_p, DROP INDEX c_p_n;
Query OK, 239 rows affected (0.00 sec)
Records: 239  Duplicates: 0  Warnings: 0

mysql&amp;gt; ALTER TABLE Country ADD INDEX n (Name);
Query OK, 239 rows affected (0.01 sec)
Records: 239  Duplicates: 0  Warnings: 0

mysql&amp;gt; EXPLAIN SELECT Name FROM Country WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 500000000 ORDER BY Name;
+----+-------------+---------+------+---------------+------+---------+------+------+-----------------------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra                       |
+----+-------------+---------+------+---------------+------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | Country | ALL  | NULL          | NULL | NULL    | NULL |  239 | Using where; Using filesort | 
+----+-------------+---------+------+---------------+------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)

mysql&amp;gt; EXPLAIN SELECT Name FROM Country FORCE INDEX (n) WHERE Continent = &apos;Asia&apos; AND population &amp;gt; 500000000 ORDER BY Name;
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | Country | index | NULL          | n    | 52      | NULL |  239 | Using where | 
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

mysql&amp;gt; alter table Country drop index n;
Query OK, 239 rows affected (0.01 sec)
Records: 239  Duplicates: 0  Warnings: 0

mysql&amp;gt; EXPLAIN SELECT * FROM City WHERE id = 1810;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | City  | const | PRIMARY       | PRIMARY | 4       | const |    1 |       | 
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.00 sec)

mysql&amp;gt; EXPLAIN SELECT * FROM City WHERE id = 1810 LIMIT 1;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | City  | const | PRIMARY       | PRIMARY | 4       | const |    1 |       | 
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.00 sec)

mysql&amp;gt; EXPLAIN SELECT * FROM City WHERE id BETWEEN 100 and 200;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | City  | range | PRIMARY       | PRIMARY | 4       | NULL |  101 | Using where | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.01 sec)

mysql&amp;gt; EXPLAIN SELECT * FROM City WHERE id &amp;gt;= 100 and id &amp;lt;= 200;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | City  | range | PRIMARY       | PRIMARY | 4       | NULL |  101 | Using where | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

mysql&amp;gt; EXPLAIN SELECT * FROM City WHERE countrycode IN (SELECT code FROM country WHERE name=&apos;Australia&apos;);
+----+--------------------+---------+-----------------+---------------+---------+---------+------+------+-------------+
| id | select_type        | table   | type            | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+--------------------+---------+-----------------+---------------+---------+---------+------+------+-------------+
|  1 | PRIMARY            | City    | ALL             | NULL          | NULL    | NULL    | NULL | 4079 | Using where | 
|  2 | DEPENDENT SUBQUERY | country | unique_subquery | PRIMARY       | PRIMARY | 3       | func |    1 | Using where | 
+----+--------------------+---------+-----------------+---------------+---------+---------+------+------+-------------+
2 rows in set (0.00 sec)

mysql&amp;gt; EXPLAIN SELECT city.* FROM City, Country WHERE city.countrycode=country.code AND country.name=&apos;Australia&apos;;
+----+-------------+---------+--------+---------------+---------+---------+------------------------+------+-------------+
| id | select_type | table   | type   | possible_keys | key     | key_len | ref                    | rows | Extra       |
+----+-------------+---------+--------+---------------+---------+---------+------------------------+------+-------------+
|  1 | SIMPLE      | City    | ALL    | NULL          | NULL    | NULL    | NULL                   | 4079 |             | 
|  1 | SIMPLE      | Country | eq_ref | PRIMARY       | PRIMARY | 3       | world.City.CountryCode |    1 | Using where | 
+----+-------------+---------+--------+---------------+---------+---------+------------------------+------+-------------+
2 rows in set (0.00 sec)

mysql&amp;gt; ALTER TABLE City ADD INDEX (countrycode);
Query OK, 4079 rows affected (0.03 sec)
Records: 4079  Duplicates: 0  Warnings: 0

mysql&amp;gt; EXPLAIN SELECT city.* FROM City, Country WHERE city.countrycode=country.code AND country.name=&apos;Australia&apos;;
+----+-------------+---------+--------+---------------+---------+---------+------------------------+------+-------------+
| id | select_type | table   | type   | possible_keys | key     | key_len | ref                    | rows | Extra       |
+----+-------------+---------+--------+---------------+---------+---------+------------------------+------+-------------+
|  1 | SIMPLE      | City    | ALL    | CountryCode   | NULL    | NULL    | NULL                   | 4079 |             | 
|  1 | SIMPLE      | Country | eq_ref | PRIMARY       | PRIMARY | 3       | world.City.CountryCode |    1 | Using where | 
+----+-------------+---------+--------+---------------+---------+---------+------------------------+------+-------------+
2 rows in set (0.00 sec)

mysql&amp;gt; ALTER TABLE Country ADD INDEX (name);
Query OK, 239 rows affected (0.00 sec)
Records: 239  Duplicates: 0  Warnings: 0

mysql&amp;gt; EXPLAIN SELECT city.* FROM City, Country WHERE city.countrycode=country.code AND country.name=&apos;Australia&apos;;
+----+-------------+---------+------+---------------+-------------+---------+--------------------+------+-------------+
| id | select_type | table   | type | possible_keys | key         | key_len | ref                | rows | Extra       |
+----+-------------+---------+------+---------------+-------------+---------+--------------------+------+-------------+
|  1 | SIMPLE      | Country | ref  | PRIMARY,Name  | Name        | 52      | const              |    1 | Using where | 
|  1 | SIMPLE      | City    | ref  | CountryCode   | CountryCode | 3       | world.Country.Code |   18 |             | 
+----+-------------+---------+------+---------------+-------------+---------+--------------------+------+-------------+
2 rows in set (0.01 sec)

mysql&amp;gt; 
&lt;/pre&gt;</description>
  <comments>http://mtocker.livejournal.com/46002.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/45342.html</guid>
  <pubDate>Mon, 06 Oct 2008 13:33:20 GMT</pubDate>
  <title>Optimizer Edge cases</title>
  <link>http://mtocker.livejournal.com/45342.html</link>
  <description>I love teaching EXPLAIN in training classes with the &lt;a href=&quot;http://dev.mysql.com/doc&quot;&gt;world.sql&lt;/a&gt; sample database.  One of my favorite edge cases to try and explain to students is:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SELECT Name FROM Country WHERE continent = &apos;Asia&apos; AND population &amp;gt; 1 000 000 000;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you add an index on Continent,Population and Population, MyISAM will choose to use the composite index (Continent,Population), whereas InnoDB will choose just the Population index.&lt;br /&gt;&lt;br /&gt;It&apos;s a simple geography question... all of the countries in the world with &amp;gt; 1B people *are* in Asia.  Since both indexes are equally effective, InnoDB chooses to use the one with the shorter key_len, despite the fact it will have to do a second stage check on the data rows to verify this.&lt;br /&gt;&lt;br /&gt;I think that this decision (shorter index) is the right one - since unless the database has index pinning, it should always factor what the cost would be to load the indexes from disk.&lt;br /&gt;&lt;br /&gt;The storage engines maintain their own statistics.  Most of the time MyISAM seems to be more accurate (See: &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/en/innodb-restrictions.html&quot;&gt;ANALYZE TABLE&lt;/a&gt;), but not today.</description>
  <comments>http://mtocker.livejournal.com/45342.html</comments>
  <category>mysql</category>
  <category>work</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/45222.html</guid>
  <pubDate>Sun, 17 Aug 2008 03:52:36 GMT</pubDate>
  <title>How fast (or slow) is MySQL Stored Procedure language?</title>
  <link>http://mtocker.livejournal.com/45222.html</link>
  <description>I had a long flight from Sydney to Edinburgh this weekend, and wanted to answer a common &lt;a href=&quot;http://www.mysql.com/training/&quot;&gt;training&lt;/a&gt; question - how fast/slow is the stored proc language in MySQL.  To do this, I started by stealing an example exercise we have in one of our exercises:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;DELIMITER // &lt;br /&gt;CREATE FUNCTION fibonacci(n INT)  &lt;br /&gt;RETURNS DOUBLE &lt;br /&gt;NO SQL &lt;br /&gt;BEGIN &lt;br /&gt;    DECLARE f1, result DOUBLE DEFAULT 0.0; &lt;br /&gt;    DECLARE f2 DOUBLE DEFAULT 1.0; &lt;br /&gt;    DECLARE cnt INT DEFAULT 1; &lt;br /&gt;    WHILE cnt &amp;lt;= n DO &lt;br /&gt;        SET result = f1 + f2; &lt;br /&gt;        SET f1 = f2; &lt;br /&gt;        SET f2 = result; &lt;br /&gt;        SET cnt = cnt + 1; &lt;br /&gt;    END WHILE; &lt;br /&gt;    RETURN result; &lt;br /&gt;END // &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If I run this a few times, here are the results:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;mysql&amp;gt; select benchmark(100, fibonacci(40000));&lt;br /&gt;+----------------------------------+&lt;br /&gt;| benchmark(100, fibonacci(40000)) |&lt;br /&gt;+----------------------------------+&lt;br /&gt;|                                0 | &lt;br /&gt;+----------------------------------+&lt;br /&gt;1 row in set (17.94 sec)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Then if I write a simple PHP script that does the same (without any further optimization)...&lt;br /&gt;&lt;code&gt;&lt;br /&gt;..&lt;br /&gt;function fibonacci ($n) {&lt;br /&gt;&lt;br /&gt;	$f1 = 0.0;&lt;br /&gt;	$result = 0.0;&lt;br /&gt;	$f2 = 1.0;&lt;br /&gt;	$cnt = 1;&lt;br /&gt;	&lt;br /&gt;	while($cnt &amp;lt;= $n) {&lt;br /&gt;		$result = $f1 + $f2;&lt;br /&gt;		$f1 = $f2;&lt;br /&gt;		$f2 = $result;&lt;br /&gt;		$cnt = $cnt+1;&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	return $result;&lt;br /&gt;}&lt;br /&gt;..&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;How long does it take?&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ php fib.php 40000 100&lt;br /&gt;Finding fib 40000, 100 times&lt;br /&gt;Took 1.7208609580994 seconds&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt; 17.94 seconds versus 1.72 seconds, so MySQL is &lt;strong&gt;ten&lt;/strong&gt; times slower!&lt;br /&gt;&lt;br /&gt;There&apos;s a small amount of overhead added to MySQL because the procedure has to load up/deconstruct 100 times and build a result to return, but by another test I think this only accounts for 0.19 seconds.</description>
  <comments>http://mtocker.livejournal.com/45222.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>9</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://mtocker.livejournal.com/44822.html</guid>
  <pubDate>Thu, 19 Jun 2008 01:21:46 GMT</pubDate>
  <title>SQL comments - commenting out code for earlier versions</title>
  <link>http://mtocker.livejournal.com/44822.html</link>
  <description>In MySQL, it&apos;s possible to comment out portions of code that you only want to work in specific MySQL versions:&lt;br /&gt;&lt;br /&gt;i.e.&lt;br /&gt;CREATE DATABASE /*!32312 IF NOT EXISTS*/ `a` /*!40100 DEFAULT CHARACTER SET latin1 */;&lt;br /&gt;&lt;br /&gt;The problem with this, is that the decimal point is omitted - and there&apos;s a real assumption that with something like 3.23.12 the &quot;12&quot; portion never exceeds 99.&lt;br /&gt;&lt;br /&gt;When I look at 5.0, MySQL is currently at 5.0.60 - and there are still minor changes happening.  5.1 is at 5.1.25, and not even GA.  Assuming that 5.1 does the same community/enterprise split and shuffles through releases in even numbers, how long will it take before we have 5.1.100?&lt;br /&gt;&lt;br /&gt;If we do get there, the SQL commenting feature will need upgrading.</description>
  <comments>http://mtocker.livejournal.com/44822.html</comments>
  <category>mysql</category>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
</channel>
</rss>
