<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-33074055</id><updated>2011-10-17T21:38:10.941+02:00</updated><category term='mysql database'/><title type='text'>Index Analyzer for MySQL</title><subtitle type='html'>Information about the Index Analysis Tool for MySQL.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-33074055.post-3554269783054448959</id><published>2009-12-02T01:45:00.000+01:00</published><updated>2009-12-02T01:45:03.353+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql database'/><title type='text'>Index Analyzer for MySQL - r123</title><content type='html'>&lt;p&gt;Thanks to a bug report that at first seemed to be merely a simple output bug, I went into the code and found two other problems. One was with the detection of duplicates in the analysis result, another one was about refreshing the GUI from a non Event Queue Thread.
&lt;/p&gt;&lt;p&gt;
Both issues have been fixed in r123.
&lt;/p&gt;&lt;p&gt;
Thanks to &lt;a href="http://code.google.com/u/barton.tomas/"&gt;barton.tomas&lt;/a&gt; for reporting this.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-3554269783054448959?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/3554269783054448959/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=3554269783054448959' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/3554269783054448959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/3554269783054448959'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2009/12/index-analyzer-for-mysql-r123.html' title='Index Analyzer for MySQL - r123'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-7946595157988605869</id><published>2009-08-30T12:10:00.002+02:00</published><updated>2009-08-30T12:19:32.082+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql database'/><title type='text'>Index Analyzer for MySQL - r120</title><content type='html'>&lt;p&gt;I finally found some time to update this little project of mine. Most notably, there was a bug - reported some time ago and partially fixed in the repository - that caused problems when column or table names contained unusual characters or conflicted with SQL keywords.&lt;/p&gt;
&lt;p&gt;This fix is now included in the current archive downloadable from the Google-Code site.&lt;/p&gt;
&lt;p&gt;Moreover I did some cleanup and prevented the app from crashing when the database was not reachable.&lt;/p&gt;
&lt;p&gt;The current release is called r120 - the Subversion revision number of the source used to build it. This is easier to track than the previous 0.0x counting.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-7946595157988605869?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/7946595157988605869/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=7946595157988605869' title='3 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/7946595157988605869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/7946595157988605869'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2009/08/index-analyzer-for-mysql-r120.html' title='Index Analyzer for MySQL - r120'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-5331505851842308169</id><published>2007-09-02T00:56:00.000+02:00</published><updated>2007-09-02T01:01:39.770+02:00</updated><title type='text'>Downloadable Version 0.05</title><content type='html'>After all I have got to build a pre-packaged version again. Thanks to the &lt;a href="http://fjep.sourceforge.net/"&gt;Fat-Jar Eclipse plugin&lt;/a&gt; it was just a matter of a few clicks.
Version 0.05 (downloadable &lt;a href="http://bismarck.shipdown.de/mia/"&gt;here&lt;/a&gt; or from the Google Code &lt;a href="http://code.google.com/p/mysqlindexanalyzer/downloads/list"&gt;download page&lt;/a&gt;) contains the changes described in the previous post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-5331505851842308169?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/5331505851842308169/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=5331505851842308169' title='15 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/5331505851842308169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/5331505851842308169'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2007/09/downloadable-version-005.html' title='Downloadable Version 0.05'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-6518300183131565630</id><published>2007-07-25T18:07:00.000+02:00</published><updated>2008-11-13T07:50:13.618+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql database'/><title type='text'>Duplicate fields in index</title><content type='html'>&lt;p&gt;It has been an really long time since I last updated. No, I have not been on vacation all the time (nevertheless I &lt;em&gt;have been&lt;/em&gt; more than once since the last post :)), but lots of work and private stuff just did not leave enough time to do any updates.&lt;/p&gt;

&lt;p&gt;So, what's new...&lt;/p&gt;

&lt;p&gt;Yesterday I looked around &lt;a href="http://video.google.com/"&gt;Google Video&lt;/a&gt; for &lt;a href="http://video.google.com/videosearch?q=google+techtalks"&gt;TechTalks&lt;/a&gt; on the hunt for something interesting and stumbled across &lt;a href="http://video.google.com/videoplay?docid=2524524540025172110"&gt;Performance Tuning Best Practices for MySQL&lt;/a&gt;. In this quite interesting - even though somewhat outdated talk - Jay mentioned again a known fact about InnoDb indexes. Internally every non-primary index on an InnoDb table is appended with the primary key fields. This is because in contrast to MyISAM where all indexes are treated the same, the primary key is a clustered index in InnoDb. See &lt;a href="http://dev.mysql.com/doc/refman/5.0/en/innodb-table-and-index.html"&gt;the manual page&lt;/a&gt; or e. g. &lt;a href="http://www.samspublishing.com/articles/article.asp?p=377069&amp;rl=1"&gt;a sample chapter&lt;/a&gt; on Query Optimization from MySQL, 3rd Edition by Sams Publishing.
This leads to an interesting situation. Consider this (hypothetical) table:&lt;/p&gt;
&lt;pre class="codeoutput"&gt;
CREATE TABLE `invoices` (
`invoicecode` char(10) NOT NULL,
`customercode` char(10) NOT NULL,
`email` varchar(45) NOT NULL,
`duedate` char(8) NOT NULL,
PRIMARY KEY  (`invoicecode`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
&lt;/pre&gt;

&lt;p&gt;The records will be physically saved in lexical &lt;code&gt;invoicecode&lt;/code&gt; order. InnoDb will store all the field data directly with the primary key. Adding an index e. g. on the &lt;code&gt;customerno&lt;/code&gt; column will copy all the &lt;code&gt;customerno&lt;/code&gt; values into a different location in their natural order. For each &lt;code&gt;customerno&lt;/code&gt; the corresponding &lt;code&gt;invoicecode&lt;/code&gt; will be stored,  there too. Looking records up by &lt;code&gt;customerno&lt;/code&gt; will first cause the secondary index to be accessed. Only then will the actual row data be accessed by a second lookup using the &lt;code&gt;invoicecode&lt;/code&gt; found for a &lt;code&gt;customerno&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;Often a single customer will have several invoices, so the database designer might come up with a combined - covering - secondary index for quicker lookups by &lt;code&gt;customerno&lt;/code&gt; and &lt;code&gt;invoicecode&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="code"&gt;
ALTER TABLE `invoices`
  ADD INDEX `idx_combined`(`customerno`, `invoicecode`);
&lt;/pre&gt;

&lt;p&gt;This seems to be a good idea, especially queries by &lt;code&gt;customerno&lt;/code&gt; are intended to retrieve only the &lt;code&gt;invoicecode&lt;/code&gt;s. In such cases MySQL is able to satisfy the request by only using the index, no second access as described above is necessary, because all required data is contained in the index itself. Using the EXPLAIN command on a query like &lt;code&gt;SELECT customerno, invoicecode FROM invoices&lt;/code&gt; will show "index" in the "type" column (or "Using index" in the "Extra" column).&lt;/p&gt;

&lt;p&gt;So everything is good, right? Well, it could be better: Because &lt;code&gt;invoicecode&lt;code&gt; is the primary key it will be appended to all other indexes. This means the &lt;code&gt;idx_combined&lt;/code&gt; index internally looks like this &lt;code&gt;(`customerno`, `invoicecode`, `invoicecode`)&lt;/code&gt; with the second &lt;code&gt;`invoicecode`&lt;code&gt; being the primary key that has been added automatically.&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Usually MySQL will give you a "Duplicate Column" error when you try to include the same column more than once in an index definition, but as this is specific to InnoDb the MySQL layer above seems not to know about this.&lt;/p&gt;

&lt;p&gt;I filled the example table with around 74.000 randomly generated records. Now explaining an example query show this:&lt;/p&gt;

&lt;pre class="code"&gt;

mysql&gt; explain select customerno, invoicecode
   -&gt;   from invoices
   -&gt;   where customerno between 1000012334 and 1050012334 \G
*************************** 1. row ***************************
         id: 1
select_type: SIMPLE
      table: invoices
       type: range
possible_keys: idx_combined
        key: idx_combined
    key_len: 4
        ref: NULL
       rows: 6110
      Extra: Using where; Using index
1 row in set (0.00 sec)
&lt;/pre&gt;

&lt;p&gt;Notice the "Using index" hint in the "Extra" column. This is because MySQL can take all the columns we want from the index. According to "key:" it is in fact using our composite key.&lt;/p&gt;

&lt;p&gt;Now we try the same thing again after modifying the idx_combined by dropping the &lt;code&gt;invoicecode&lt;/code&gt; column from it:&lt;/p&gt;

&lt;pre class="code"&gt;
mysql&gt; ALTER TABLE `test`.`invoices`
   -&gt;    DROP INDEX `idx_combined`,
   -&gt;    ADD INDEX `idx_customerno` (`customerno`);

mysql&gt; explain select customerno, invoicecode
   -&gt;     from invoices
   -&gt;     where customerno between 1000012334 and 1050012334 \G
*************************** 1. row ***************************
         id: 1
select_type: SIMPLE
      table: invoices
       type: range
possible_keys: idx_customerno
        key: idx_customerno
    key_len: 4
        ref: NULL
       rows: 6174
      Extra: Using where; Using index
1 row in set (0.00 sec)
&lt;/pre&gt;

&lt;p&gt;As you can see, the new index is used, which contains only one (visible) column, but still the "Using index" hint is shown, which means no lookups to the actual data was needed to fulfill the request.&lt;/p&gt;

&lt;p&gt;Dropping the explicit &lt;code&gt;invoicecode&lt;/code&gt; column from the &lt;code&gt;idx_combined&lt;/code&gt; index will reduce the size of an index record by about a third, i. e. from 30 to 20 bytes per record. This allows more index records to fit into a single buffer page, in effect allowing for more efficient use of your memory - the more entries per page the more efficient your buffer pool memory can be used and the better your performance can get.&lt;/p&gt;

&lt;p&gt;I added support for detecting this kind of redundancy in MySQL Index Analyzer. While at it I also improved the looks a little, utilizing some icons from Eclipse.
Analyzing the simple example above will result in this output:&lt;/p&gt;

&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_jZVk_i0f9PM/Rqe7G9SiHGI/AAAAAAAAABk/rF_sSqfBQVE/s1600-h/idx_duplicate_cols_1.png"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_jZVk_i0f9PM/Rqe7G9SiHGI/AAAAAAAAABk/rF_sSqfBQVE/s400/idx_duplicate_cols_1.png" alt="" id="BLOGGER_PHOTO_ID_5091243631971540066" border="0" /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;There is no pre-build package so far, and I do not know when I will get to build one. But feel free to always get the latest version from SVN.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-6518300183131565630?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/6518300183131565630/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=6518300183131565630' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/6518300183131565630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/6518300183131565630'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2007/07/duplicate-fields-in-index.html' title='Duplicate fields in index'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_jZVk_i0f9PM/Rqe7G9SiHGI/AAAAAAAAABk/rF_sSqfBQVE/s72-c/idx_duplicate_cols_1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-1240501006922111092</id><published>2006-10-08T03:11:00.000+02:00</published><updated>2006-10-08T03:28:07.065+02:00</updated><title type='text'>Stored Connections, Improved Size Estimates</title><content type='html'>&lt;p&gt;The current SVN trunk revision contains two interesting changes which however I have not put into a new package, because they are not final (enough ;)) yet.&lt;/p&gt;
&lt;p&gt;What has been happening recently is&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Stored Connections&lt;/p&gt;
&lt;p&gt;I have implemented stored connection profiles, mostly because I had to enter the login data each an every time I ran the app to test something. This is based on the &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/prefs/package-summary.html"&gt;Java Preferences API&lt;/a&gt; which in this case uses a simple file backend. Currently passwords are stored in plain text, so please be careful not to save anything important should you decide to try it out.&lt;/p&gt;&lt;p&gt;In order use the new feature, you will find a new button in the connection dialog to store the data currently shown. To load a saved session, just select it from the drop down combobox.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improved size estimate for InnoDB&lt;/p&gt;
&lt;p&gt;Based on &lt;a href="http://www.mysqlperformanceblog.com/2006/10/03/mysql-optimizer-and-innodb-primary-key/#more-108"&gt;Peter Zaitsev's article&lt;/a&gt; about the MySQL Optimizer and InnoDB primary keys I changed the calculation of the index size for InnoDB tables. I knew this before, but had not thought about integrating it into the Index Analyzer.&lt;/p&gt;&lt;p&gt;To get more details read the MySQL manual and of course Peter's article. The main point however is that InnoDB indices other than the primary index always contain the primary index columns as an (implicit, invisible) suffix, so large primary keys can increase any other index's size significantly. This is now considered when calculating estimated savings.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I will try to get a new package ready soon, however I am preparing for a vacation, so it might be delayed a little.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-1240501006922111092?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/1240501006922111092/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=1240501006922111092' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/1240501006922111092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/1240501006922111092'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2006/10/stored-connections-improved-size.html' title='Stored Connections, Improved Size Estimates'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-6173976760387253229</id><published>2006-09-26T07:40:00.000+02:00</published><updated>2006-09-26T07:43:29.143+02:00</updated><title type='text'>Stupid bug in 0.04</title><content type='html'>&lt;p&gt;Yesterday I noticed that the overall database size calculation in 0.04 contains a very stupid bug. While iterating the tables, only their index sizes get added up correctly, while the table data size does not. The display always shows the size of the last table analyzed, so with a single table example, you will not see any difference.&lt;/p&gt;
&lt;p&gt;You can check out the trunk version vom SVN to have this fixed before the next release.&lt;/p&gt;
&lt;p&gt;Currently I am working on stored connection profiles, which is especially interesting to myself right now, because currently I have to type in the login information each time I run the thing to test it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-6173976760387253229?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/6173976760387253229/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=6173976760387253229' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/6173976760387253229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/6173976760387253229'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2006/09/stupid-bug-in-004.html' title='Stupid bug in 0.04'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-538263286106256243</id><published>2006-09-23T02:49:00.000+02:00</published><updated>2006-09-23T02:51:54.235+02:00</updated><title type='text'>MySQL Index Analyzer: 0.04 released</title><content type='html'>&lt;p&gt;&lt;a href="http://bismarck.shipdown.de/mia/"&gt;Version 0.04&lt;/a&gt; of the MySQL Index Analyzer has just been uploaded. This is the first version that features a Swing GUI and actually provides real analysis functions and the generation of ALTER TABLE statements to get rid of superfluous indices.&lt;/p&gt;
&lt;p&gt;A quick overview of what is new:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Swing GUI&lt;/li&gt;
  &lt;li&gt;Analysis features as on the command line&lt;/li&gt;
  &lt;li&gt;Copying of generated ALTER TABLE statements to the clipboard&lt;/li&gt;
  &lt;li&gt;Information on data and index size distribution&lt;/li&gt;
  &lt;li&gt;Rudimentary analysis of possible disk space savings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Especially the size analysis is in a very early stage and will probably be way off most of the time. I do however plan to spend more work there, because I think this is a very important point.&lt;/p&gt;
&lt;p&gt;Documentation in the distribution file is somewhat outdated, but I will give some more details here. The following example is based on a simple database with only one table called &lt;code&gt;people&lt;/code&gt;. The table consists of four columns:&lt;/p&gt;
&lt;pre class="code"&gt;
 CREATE TABLE `people` (
  `id` int(11) NOT NULL auto_increment,
  `firstname` varchar(32) default NULL,
  `lastname` varchar(32) default NULL,
  `birthday` date default NULL,
  PRIMARY KEY  (`id`),
  KEY `idx_reversename` (`lastname`,`firstname`),
  KEY `idx_id_birth_first` (`id`,`birthday`,`firstname`),
  KEY `idx_full` (`firstname`,`lastname`),
  KEY `idx_first` (`firstname`),
  KEY `idx_id_first` (`id`,`firstname`),
  KEY `idx_id_birth` (`id`,`birthday`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 
&lt;/pre&gt;
&lt;p&gt;There are 7 indices defined on that table, including the PRIMARY key.&lt;/p&gt;
&lt;p&gt;Now let's see what the MySQLIndexAnalyzer has to say:&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bismarck.shipdown.de/miapics/login.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://bismarck.shipdown.de/miapics/login.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After login, the analysis starts immediately. I will implement a more fine grained control later, for now, the whole schema is analyzed:&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bismarck.shipdown.de/miapics/analyze.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://bismarck.shipdown.de/miapics/analyze.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;
Thanks to the great folks of &lt;a href="https://swingfx.dev.java.net/"&gt;swingfx.dev.java.net&lt;/a&gt; waiting is done with some style ;)&lt;/p&gt;
&lt;p&gt;As soon as the analysis is ready, you will see a screen like this:&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bismarck.shipdown.de/miapics/result.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://bismarck.shipdown.de/miapics/result.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;
In the upper part of the Window you see some general information about data and index sizes. The Index/Data Ration of 3.0 means, that indices for this database need 3 times the amount of space the real data eats up. This ratio is also displayed as a bar. Please be aware, that all numbers only refer to the tables shown in the details view below, the database might be a lot bigger!&lt;/p&gt;
&lt;p&gt;The lower part shows a hierarchical view of the database structure. Tables are shown as little folders, detected index obsoletions are the leafs below them. In the example you can see, that 2 indices where found (&lt;code&gt;idx_first, idx_id_birth&lt;/code&gt;) which can be safely removed, because they are only prefixes of &lt;code&gt;idx_full&lt;/code&gt; and &lt;code&gt;idx_id_birth_first&lt;/code&gt;. For each obsoletion and estimated amount of disk space savings is displayed that would result from dropping that particular index. On the table level you see the sum of all obsoleted indices savings.&lt;/p&gt;
&lt;p&gt;Via the "Generate DML" button you get to this dialog:&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bismarck.shipdown.de/miapics/genoptions.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://bismarck.shipdown.de/miapics/genoptions.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;From here you can either save the DML (ALTER TABLE) statements to a file or store them to the system clipboard: &lt;em&gt;(Please do not blindly apply them to your database!)&lt;/em&gt;&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bismarck.shipdown.de/miapics/clipboard.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://bismarck.shipdown.de/miapics/clipboard.png" border="0" alt="" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Please let me know I you find this tool helpful, have suggestions on what to improve/include, and of course, if you'd like to participate in the development.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-538263286106256243?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://bismarck.shipdown.de/mia/' title='MySQL Index Analyzer: 0.04 released'/><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/538263286106256243/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=538263286106256243' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/538263286106256243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/538263286106256243'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2006/09/mysql-index-analyzer-004-released_23.html' title='MySQL Index Analyzer: 0.04 released'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-115865853346805120</id><published>2006-09-19T11:33:00.000+02:00</published><updated>2006-09-19T11:35:33.480+02:00</updated><title type='text'>Internet Explorer Problems</title><content type='html'>&lt;p&gt;In case you have display problems with MS Internet Explorer, try changing the font size up- and down (e. g. hold Strg and scroll with your mouse wheel once up, once down). This should correct the rendering. As I normally do not use IE (too clumsy to do on Linux) I did only notice the problem today.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-115865853346805120?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/115865853346805120/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=115865853346805120' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115865853346805120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115865853346805120'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2006/09/internet-explorer-problems.html' title='Internet Explorer Problems'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-115861281672695129</id><published>2006-09-18T22:51:00.000+02:00</published><updated>2006-09-19T08:13:45.333+02:00</updated><title type='text'>GUI coming along</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6759/3578/1600/1.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/6759/3578/320/1.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Just a quick update: If you check out the latest trunk version from the subversion repository you will get a working GUI version. After you connected to the database, the analysis will start and the results be displayed in a tree control.&lt;/p&gt;
&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6759/3578/1600/2.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/6759/3578/320/2.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The upper half of the result display is still non-functional, and there is nothing more you can do than look at the result, but I thought someone might be interested in this intermediate step.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-115861281672695129?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/115861281672695129/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=115861281672695129' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115861281672695129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115861281672695129'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2006/09/gui-coming-along.html' title='GUI coming along'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-115830484781292461</id><published>2006-09-15T09:15:00.000+02:00</published><updated>2006-09-15T09:22:06.940+02:00</updated><title type='text'>More refactoring is on the way</title><content type='html'>&lt;p&gt;On the way to a modular design I refactored the source to provide the output through rendering modules. The text output is the first one of those. So from the end-user perspective nothing has changed with the &lt;a href="http://bismarck.shipdown.de/mia/mia_0.03.zip"&gt;version 0.03 package&lt;/a&gt; available now (except that it has grown bigger).&lt;/p&gt;
&lt;p&gt;The larger download is however mostly caused by more libraries being included, especially those for the graphical interface that I have just begun. Currently it only provides a login view which lets you connect to the database. However no analysis can be started yet. If you want to have a look at what I intend to let the GUI look like, just modify the main class in the launcher script to &lt;code&gt;de.shipdown....gui.MySQLIndexAnalyzer&lt;/code&gt;. I will try to get the first graphical version to actually show something soon.&lt;/p&gt;
&lt;p&gt;As for the previous version: To use the package, just download and unzip into a new directory. For use on Linux make sure you chmod the "mia" script to make it executable. On both Windows and Linux you have to have a java executable on your path. If you have not, edit the "mia" or "mia.cmd" script to include the full path.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-115830484781292461?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://bismarck.shipdown.de/mia/' title='More refactoring is on the way'/><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/115830484781292461/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=115830484781292461' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115830484781292461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115830484781292461'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2006/09/more-refactoring-is-on-way.html' title='More refactoring is on the way'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-115680871034212918</id><published>2006-08-29T01:41:00.000+02:00</published><updated>2006-08-29T01:45:10.390+02:00</updated><title type='text'>First downloadable release 0.02</title><content type='html'>&lt;p&gt;I just uploaded the first ready-to-use package of the MySQL Index Analyzer (version 0.02). You can download it via &lt;a href="http://bismarck.shipdown.de/mia/mia_0.02.zip"&gt;http://bismarck.shipdown.de/mia/mia_0.02.zip&lt;/a&gt; or click on the "Downloads" link in the sidebar.&lt;/p&gt;
&lt;p&gt;This is still a command-line only version, but the DDL generation support has been enabled again.&lt;/p&gt;
&lt;p&gt;To use the package, just download and unzip into a new directory. For use on Linux make sure you &lt;code&gt;chmod&lt;/code&gt; the "mia" script to make it executable. On both Windows and Linux you have to have a &lt;code&gt;java&lt;/code&gt; executable on your path. If you have not, edit the "mia" or "mia.cmd" script to include the full path.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-115680871034212918?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://bismarck.shipdown.de/mia/mia_0.02.zip' title='First downloadable release 0.02'/><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/115680871034212918/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=115680871034212918' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115680871034212918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115680871034212918'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2006/08/first-downloadable-release-002.html' title='First downloadable release 0.02'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-115654840312812413</id><published>2006-08-26T01:07:00.000+02:00</published><updated>2006-08-26T01:29:00.953+02:00</updated><title type='text'>Refactoring, Step 1: IndexDescriptorProvider</title><content type='html'>&lt;p&gt;Development of a more structured version is in progress. I just committed a set of changes to the repository that changes the current, rather monolithic, single-class design to what will be the first step of a more modular one.&lt;/p&gt;
&lt;p&gt;Currently the generation of &lt;code&gt;ALTER TABLE&lt;/code&gt; statements has been removed and the output format of the analysis is slightly different. But that is mere cosmetic&lt;/p&gt;
&lt;p&gt;What is much more important is that now the gathering of database schema information is based on a pluggable system, designed around an interface called &lt;code&gt;IndexDescriptorProvider&lt;/code&gt;. Up to now I have just ported the MySQL 4 stuff that was already in the first version to this new architecture. Please feel free to have a look at it and tell me what you think.&lt;/p&gt;
&lt;p&gt;Next thing I'll do is implement a provider based on the &lt;code&gt;INFORMATION_SCHEMA&lt;/code&gt; database available in MySQL 5.x to see if I missed anything.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-115654840312812413?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/115654840312812413/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=115654840312812413' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115654840312812413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115654840312812413'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2006/08/refactoring-step-1-indexdescriptorprov.html' title='Refactoring, Step 1: IndexDescriptorProvider'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-115645257795692276</id><published>2006-08-24T22:31:00.000+02:00</published><updated>2006-08-25T09:39:18.876+02:00</updated><title type='text'>Basic documentation</title><content type='html'>&lt;p&gt;While the work to refactor the DuplicateIndexFinder is going on (however not quite as fast as I would like it to), here is some general information about what exists already.&lt;/p&gt;
&lt;h1&gt;Why does it exist?&lt;/h1&gt;
&lt;p&gt;The DuplicateIndexFinder class was written, because we have an application that works with a database schema of some 500 tables. Those tables are generated by an object relation persistence mapper from UML diagrams. While the framework used (proprietary) works very well and allows for quick and efficient application development, the generated schema is not perfect.&lt;/p&gt;
&lt;p&gt;The schema contains a lot of generically generated index definitions that are not necessary from the database perspective. For example for all tables an index that covers the primary key fields is created, in addition to the primary key. This is especially useless, because it will never be used by the optimizer.&lt;/p&gt;
&lt;p&gt;However this is not the only problem. As the schema is generated automatically and the generator tool does not analyze table depencies in advance for the whole schema, a good deal of indices are created that cover a prefix of a longer index.&lt;/p&gt;
&lt;p&gt;While there may be situations where indices become very long and a second, shorter index on a prefix may be sensible, usually the extra space used in the tablespace is not worth it. As we are dealing with several hundred databases, each about 100GB in size, superfluous indices can become a real pain in the neck. This is why I hacked this little tool.&lt;/p&gt;
&lt;h1&gt;What can it do?&lt;/h1&gt;
&lt;p&gt;Currently the whole point of the MySQL Index Analyzer is really just the detection of duplicate/superfluous indices. However I plan to include much more functionality over time. Right now you can let it look at a database and it will output a text report of which indices are obsoleted by other, longer indices on the same table. Moreover it can generate DDL statements in MySQL syntax that remove the unneeded indices from the tables, therefore releasing the space they occupied before.&lt;/p&gt;
&lt;h1&gt;How to use it?&lt;/h1&gt;
&lt;p&gt;The DuplicateIndexFinder is a single Java class that can be run as a command line application. Apart from a Java Runtime Environment you will also need the MySQL JDBC Driver (Connector/J) and the JSAP library (Java-based Simple Argument Parser). The tool has been written using Java 5,but apart from some generic collections nothing fancy is used. I believe it should be possible to compile Java 1.4 compliant version, even though I did not try it myself.&lt;/p&gt;
&lt;p&gt;To get an overview of its usage, just run it as follows on a command line:&lt;/p&gt;
&lt;pre class="code"&gt;java de.shipdown.util.mysql.DuplicateIndexFinder --help&lt;/pre&gt;
&lt;p&gt;This will output general usage information and short explanations for the available options:&lt;/p&gt;
&lt;pre class="code"&gt;

Usage: java de.shipdown.util.mysql.DuplicateIndexFinder
                [--help] [(-o|--outfile) &amp;lt;outfile&amp;gt;] [-v|--verbose] [-a|--generate-alter-table] (-D|--database) &amp;lt;dbname&amp;gt; (-u|--user) &amp;lt;dbuser&amp;gt; [(-p|--password) &amp;lt;dbpass&amp;gt;] [(-h|--host) &amp;lt;dbhost&amp;gt;] [(-P|--port) &amp;lt;dbport&amp;gt;]

  [--help]
        Prints this help message.

  [(-o|--outfile) &amp;lt;outfile&amp;gt;]
        Name of an output file. StdOut if omitted.

  [-v|--verbose]
        Requests verbose output (includes column names).

  [-a|--generate-alter-table]
        Generate alter table statements to drop superfluous indices.

  (-D|--database) &amp;lt;dbname&amp;gt;
        Name of the database to analyze.

  (-u|--user) &amp;lt;dbuser&amp;gt;
        User name for database connection.

  [(-p|--password) &amp;lt;dbpass&amp;gt;]
        Password for database connection.

  [(-h|--host) &amp;lt;dbhost&amp;gt;]
        Database hostname or address to connect to. Defaults to localhost.
        (default: localhost)

  [(-P|--port) &amp;lt;dbport&amp;gt;]
        Database network port. Defaults to 3306. (default: 3306)
&lt;/pre&gt;
&lt;p&gt;As you can see most options are designed to be compatible with the usual MySQL command line tools. The only required parameters are the user and database names. All other options have sensible defaults.&lt;/p&gt;
&lt;p&gt;If you specify the &lt;code&gt;--generate-alter-table&lt;/code&gt; option, you will not only get an analysis of the indices in you database, but also suggessted &lt;code&gt;ALTER TABLE&lt;/code&gt; statements. Please make sure you do not blindly apply those to any database. While I do not think anything horrible can happen, I cannot make any guarantee. It never hurts to have a backup!&lt;/p&gt;
&lt;p&gt;Using the &lt;code&gt;--verbose&lt;/code&gt; option the report will contain column names, so you can see for yourself if an index is really just a prefix of a longer one.&lt;/p&gt;
&lt;h1&gt;Example&lt;/h1&gt;
&lt;p&gt;Consider a database "test" with a single table "people" with the following definition:&lt;/p&gt;
&lt;pre class="code"&gt;
 CREATE TABLE `people` (
  `id` int(10) unsigned NOT NULL,
  `firstname` varchar(32) default NULL,
  `lastname` varchar(32) default NULL,
  `birthday` date default NULL,
  PRIMARY KEY  (`id`),
  KEY `idx_id` (`id`),
  KEY `idx_first` (`firstname`),
  KEY `idx_last` (`lastname`),
  KEY `idx_fullname` (`firstname`,`lastname`),
  KEY `idx_reversename` (`lastname`,`firstname`),
  KEY `idx_id_birth` (`id`,`birthday`),
  KEY `idx_id_birth_first` (`id`,`birthday`,`firstname`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
&lt;/pre&gt;
&lt;p&gt;Now without further ado just run the DuplicateIndexFinder (the example assumes that you checked out the tag "0.01" from the SVN repository to &lt;code&gt;~/workspace/MIA0.01&lt;/code&gt;):&lt;/p&gt;
&lt;pre class="code"&gt;
ds@yavin:~/workspace/MIA0.01
$ java -cp lib/mysql-connector-java-3.1.13-bin.jar:lib/JSAP-2.1.jar:build de.shipdown.util.mysql.DuplicateIndexFinder -u ds -D test

Table people
--------------------------------------------------------------------------------
PRIMARY (len:1)
    obsoletes idx_id (len:1)
idx_reversename (len:2)
    obsoletes idx_last (len:1)
idx_fullname (len:2)
    obsoletes idx_first (len:1)
idx_id_birth (len:2)
    obsoletes idx_id (len:1)
idx_id_birth_first (len:3)
    obsoletes idx_id (len:1)
    obsoletes idx_id_birth (len:2)
&lt;/pre&gt;
&lt;p&gt;This output means&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;that the PRIMARY key obsoletes the idx_id, because they are identical. The primary key is always preserved.&lt;/li&gt;
&lt;li&gt;that idx_reversename makes idx_last obsolete, because any query that searches for just a last name can just as well use the idx_reversename index, as can a query that looks for a full name combination&lt;/li&gt;
&lt;li&gt;that idx_fullname makes idx_first useless for the same reason as above&lt;/li&gt;
&lt;li&gt;that idx_id_birth obsoletes idx_id for the same reason as above. Note that the id column is also covered by the primary key.&lt;/li&gt;
&lt;li&gt;that idx_id_birth_first obsoletes both idx_id and id_id_birth, because it starts with the same columns as the other two.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you follow the tool's advice you would modify your schema to remove all indices except for the primary key, idx_reversename, idx_fullname, and idx_id_birth_first. You can get the necessary statements to drop the obsolete one like this:&lt;/p&gt;
&lt;pre class="code"&gt;
ds@yavin:~/workspace/MIA 0.01
$ java -cp lib/mysql-connector-java-3.1.13-bin.jar:lib/JSAP-2.1.jar:build de.shipdown.util.mysql.DuplicateIndexFinder -u ds -D test --verbose --generate-alter-table

Table people
--------------------------------------------------------------------------------
PRIMARY (cols: 1:id)
    obsoletes idx_id (cols: 1:id)
idx_reversename (cols: 1:lastname, 2:firstname)
    obsoletes idx_last (cols: 1:lastname)
idx_fullname (cols: 1:firstname, 2:lastname)
    obsoletes idx_first (cols: 1:firstname)
idx_id_birth (cols: 1:id, 2:birthday)
    obsoletes idx_id (cols: 1:id)
idx_id_birth_first (cols: 1:id, 2:birthday, 3:firstname)
    obsoletes idx_id (cols: 1:id)
    obsoletes idx_id_birth (cols: 1:id, 2:birthday)


ALTER TABLE STATEMENTS (PLEASE(!) REVIEW, NO WARRANTY FOR ANY DAMAGE TO YOUR DATABASE)
======================================================================================
ALTER TABLE people DROP INDEX idx_first, DROP INDEX idx_last, DROP INDEX idx_id_birth, DROP INDEX idx_id;
&lt;/pre&gt;
&lt;p&gt;As you see the &lt;code&gt;--verbose&lt;/code&gt; switch provides a little more detail in the report. But more interestingly you get a suggested DDL statement. Note that all indices are dropped at once. This is especially important for large tables, as MySQL needs to create a full copy of a table if you issue an ALTER TABLE command.&lt;/p&gt;
&lt;p&gt;Using this syntax requires only a single copy process, while removing the indices in separate statements would have required 4 copies and therefore about 4x as long.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-115645257795692276?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/115645257795692276/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=115645257795692276' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115645257795692276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115645257795692276'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2006/08/basic-documentation.html' title='Basic documentation'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-115614185666734826</id><published>2006-08-21T08:26:00.000+02:00</published><updated>2006-08-21T09:07:00.513+02:00</updated><title type='text'>Welcome to the MySQL Index Analyzer Blog</title><content type='html'>&lt;p&gt;This is the new blog for the MySQL Index Analyzer, a small Java application written by &lt;a href="http://jroller.com/pager/dschneller"&gt;Daniel Schneller&lt;/a&gt;. It was first "released" in the beginning of 2006 in &lt;a href="http://jroller.com/page/dschneller?entry=mysql_indices"&gt;this blog post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When I read questions about such a tool on the &lt;a href="http://www.mysqlperformanceblog.com"&gt;MySQL Performance Blog&lt;/a&gt; I decided to release it as a regular open source project. It currently hosted on Google's new code hosting service. You can find it here: &lt;a href="http://code.google.com/p/mysqlindexanalyzer/"&gt;http://code.google.com/p/mysqlindexanalyzer/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;More information can be found here soon.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-115614185666734826?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysql-index-analyzer.blogspot.com/feeds/115614185666734826/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33074055&amp;postID=115614185666734826' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115614185666734826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/115614185666734826'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2006/08/welcome-to-mysql-index-analyzer-blog.html' title='Welcome to the MySQL Index Analyzer Blog'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33074055.post-7606342335054835256</id><published>2006-08-20T16:45:00.004+02:00</published><updated>2009-08-30T16:50:54.090+02:00</updated><title type='text'>Impressum</title><content type='html'>Daniel Schneller&lt;br /&gt;
Kamper Str. 14&lt;br /&gt;
42699 Solingen&lt;br /&gt;
Deutschland /Germany&lt;br /&gt;
&lt;br /&gt;
Dies ist eine private Internetpräsenz.
&lt;br /&gt;
Internet: http://mysql-index-analyzer.blogspot.com
&lt;br /&gt;
Haftungshinweis: Trotz sorgfältiger inhaltlicher Kontrolle übernehmen wir keine Haftung für die Inhalte externer Links. Für den Inhalt der verlinkten Seiten sind ausschließlich deren Betreiber verantwortlich.
&lt;br /&gt;
Layout und Gestaltung dieser Website sowie die enthaltenen Informationen sind gemäß dem Urheberrechtsgesetz geschützt.
Das ist auch zu beachten, wenn auf diesen Internetseiten erscheinende Materialien Dritter zur Informationsgewinnung verwendet oder kopiert werden.
&lt;br /&gt;
Alle Angaben erfolgen ohne Gewähr. Eine Haftung für Schäden, die sich aus der Verwendung der veröffentlichten Inhalte ergeben, ist ausgeschlossen.
&lt;br /&gt;
Sollte der Inhalt oder die Aufmachung dieser Seiten Rechte Dritter oder gesetzliche Bestimmungen verletzen, bitten wir um eine entsprechende Nachricht ohne Kostennote.
&lt;br /&gt;
Wir greifen auf Drittanbieter zurück, um Anzeigen zu schalten, wenn Sie unsere Website besuchen. Diese Unternehmen nutzen möglicherweise Informationen zu Ihren Besuchen dieser und anderer Websites, damit Anzeigen zu Produkten und Diensten geschaltet werden können, die Sie interessieren. Falls Sie mehr über diese Methoden erfahren möchten oder wissen möchten, welche Möglichkeiten bestehen, diese Informationen nicht von den Unternehmen verwenden zu lassen, klicken Sie bitte hier: &lt;a href="http://www.google.de/privacy.html"&gt;http://www.google.de/privacy.html&lt;/a&gt;
&lt;br /&gt;
Diese Website benutzt Google Analytics, einen Webanalysedienst der Google Inc., um eine Analyse der Benutzung der Website zu ermöglichen. Die durch den Einsatz von Google Analytics erzeugten Informationen über Ihre Nutzung dieser Website (einschließlich Ihrer IP-Adresse) werden an einen Server der Google Inc. in den USA übertragen und dort gespeichert. Google wird diese Informationen lediglich dazu verwenden, die Nutzung der Website zu analysieren, indem anonymisierte Auswertungen und Grafiken zur Anzahl der Besuche, Anzahl der pro Nutzer aufgerufenen Seiten usw. erstellt werden.
&lt;br /&gt;
Das Copyright für Bilder auf der Seite liegt bei Daniel Schneller bzw. den jeweilig angegeben Personen.
&lt;br /&gt;
Dieses Impressum basiert auf der Arbeit von &lt;a href="http://www.martin-hamann.de/kalender_neu.htm"&gt;Martin Hamann&lt;/a&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33074055-7606342335054835256?l=mysql-index-analyzer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/7606342335054835256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33074055/posts/default/7606342335054835256'/><link rel='alternate' type='text/html' href='http://mysql-index-analyzer.blogspot.com/2006/08/impressum.html' title='Impressum'/><author><name>Daniel Schneller</name><uri>http://www.blogger.com/profile/10703859800169283952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_jZVk_i0f9PM/SkHQpS95gLI/AAAAAAAAB1U/f045AhTI3mI/S220/schneller_klein.jpg'/></author></entry></feed>
