<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.2.2" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title>Comments on: How to find duplicate and redundant indexes in MySQL</title>
	<link>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/</link>
	<description>Stay curious!</description>
	<pubDate>Sun, 20 Jul 2008 11:32:31 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2.2</generator>

	<item>
		<title>By: Vaibogam S</title>
		<link>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-14302</link>
		<author>Vaibogam S</author>
		<pubDate>Mon, 17 Mar 2008 14:56:57 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-14302</guid>
		<description>A simple way to find out duplicate indexes...

SELECT * FROM information_schema.statistics WHERE table_schema = '?' GROUP BY table_schema, table_name, column_name HAVING count(column_name) &#62; 1;

In the above query bind the 'database name' parameter.

-Bog</description>
		<content:encoded><![CDATA[<p>A simple way to find out duplicate indexes&#8230;</p>
<p>SELECT * FROM information_schema.statistics WHERE table_schema = &#8216;?&#8217; GROUP BY table_schema, table_name, column_name HAVING count(column_name) &gt; 1;</p>
<p>In the above query bind the &#8216;database name&#8217; parameter.</p>
<p>-Bog</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Xaprb</title>
		<link>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-6229</link>
		<author>Xaprb</author>
		<pubDate>Thu, 03 May 2007 13:16:18 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-6229</guid>
		<description>&lt;p&gt;Indexes require space, time and other work to maintain.  They slow down writes.  You can read more by following the link to Peter Zaitsev's article at the top of the page.&lt;/p&gt;</description>
		<content:encoded><![CDATA[<p>Indexes require space, time and other work to maintain.  They slow down writes.  You can read more by following the link to Peter Zaitsev&#8217;s article at the top of the page.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: suyog kale</title>
		<link>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-6218</link>
		<author>suyog kale</author>
		<pubDate>Thu, 03 May 2007 07:13:48 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-6218</guid>
		<description>&lt;p&gt;what is loss of having 
multiple indexes on same column?&lt;/p&gt;</description>
		<content:encoded><![CDATA[<p>what is loss of having<br />
multiple indexes on same column?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: suyog</title>
		<link>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-6217</link>
		<author>suyog</author>
		<pubDate>Thu, 03 May 2007 07:12:45 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-6217</guid>
		<description>&lt;p&gt;so 
its clear that in a table we have multiple indexes on same column&lt;/p&gt;</description>
		<content:encoded><![CDATA[<p>so<br />
its clear that in a table we have multiple indexes on same column</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Xaprb</title>
		<link>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-1987</link>
		<author>Xaprb</author>
		<pubDate>Tue, 26 Sep 2006 12:31:49 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-1987</guid>
		<description>&lt;p&gt;Roland has written a &lt;a href="http://forge.mysql.com/snippets/view.php?id=45" rel="nofollow"&gt;pure-SQL duplicate index finder&lt;/a&gt; and posted it on MySQL Forge.  Nice job Roland!&lt;/p&gt;</description>
		<content:encoded><![CDATA[<p>Roland has written a <a href="http://forge.mysql.com/snippets/view.php?id=45" rel="nofollow">pure-SQL duplicate index finder</a> and posted it on MySQL Forge.  Nice job Roland!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Xaprb</title>
		<link>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-1855</link>
		<author>Xaprb</author>
		<pubDate>Sun, 17 Sep 2006 16:25:55 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-1855</guid>
		<description>&lt;p&gt;Hi Dmitri, sorry I didn't respond promptly.  I lost track of which comments I needed to respond to.  You have a good point about FULLTEXT.  I have an idea about how to exclude this pretty easily.  Of course, as I said above, even if it gives some false positives you can still notice them.  Indexes are so tricky that I don't think a computer could be smart enough to replace a good DBA, so it suits me OK to have some false positives.  Better that than false negatives.&lt;/p&gt;

&lt;p&gt;Hi Roland, that's a very good point.  I should clarify something.  The script compares prefixes on indexes, but for foreign keys it compares the entire definition (excluding the name) so it won't think FKs to (col1) and (col1, col2) are duplicates of each other.  This is as it should be, as you point out.&lt;/p&gt;

&lt;p&gt;See, my Advanced Patented Algorithm (tm) for detecting foreign keys is different from indexes!  Tricky! ;-)&lt;/p&gt;

&lt;p&gt;But your second point is true, too.  A FK on multiple columns is functionally the same regardless of column order.  String comparison can't catch those.  My first thought was "well, I'm going to have to parse out column names and do a bunch of fancy stuff..." but there's an easier way that occurs to me now.&lt;/p&gt;

&lt;p&gt;I'll make these improvements and write another article about them in a bit.&lt;/p&gt;</description>
		<content:encoded><![CDATA[<p>Hi Dmitri, sorry I didn&#8217;t respond promptly.  I lost track of which comments I needed to respond to.  You have a good point about FULLTEXT.  I have an idea about how to exclude this pretty easily.  Of course, as I said above, even if it gives some false positives you can still notice them.  Indexes are so tricky that I don&#8217;t think a computer could be smart enough to replace a good DBA, so it suits me OK to have some false positives.  Better that than false negatives.</p>
<p>Hi Roland, that&#8217;s a very good point.  I should clarify something.  The script compares prefixes on indexes, but for foreign keys it compares the entire definition (excluding the name) so it won&#8217;t think FKs to (col1) and (col1, col2) are duplicates of each other.  This is as it should be, as you point out.</p>
<p>See, my Advanced Patented Algorithm &#8482; for detecting foreign keys is different from indexes!  Tricky! ;-)</p>
<p>But your second point is true, too.  A FK on multiple columns is functionally the same regardless of column order.  String comparison can&#8217;t catch those.  My first thought was &#8220;well, I&#8217;m going to have to parse out column names and do a bunch of fancy stuff&#8230;&#8221; but there&#8217;s an easier way that occurs to me now.</p>
<p>I&#8217;ll make these improvements and write another article about them in a bit.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Roland Bouman</title>
		<link>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-1853</link>
		<author>Roland Bouman</author>
		<pubDate>Sun, 17 Sep 2006 15:27:23 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-1853</guid>
		<description>&lt;p&gt;Hi Xaprb/Baron,&lt;/p&gt;

&lt;p&gt;Great tool. I have a question though. I was wondering why the project appears as "Duplicate index/foreign key finder" on MySQLForge.&lt;/p&gt;

&lt;p&gt;I really know next to nothing about perl so I might miss an important point by not understanding the code, but it seems to me that if this script really compares the strings from the &lt;code&gt;SHOW CREATE TABLE&lt;/code&gt; output like described above, it can in no way spot all duplicate or redundant foreign key definitions.&lt;/p&gt;

&lt;p&gt;It depends on what you call a duplicate foreign key of course. I mean, suppose the (innoDB) parent table would have an index on (col1,col2) then I can create two foreign key constraints in the child table, one that references just (col1), and one that references (col1,col2). I suppose the script would catch these cases. However, I would not call those 'duplicate' foreign keys. I would prefer 'spurious' or 'redundant'. Take a look at this example:&lt;/p&gt;

&lt;pre&gt;CREATE TABLE `c` (
  `name` varchar(10) DEFAULT NULL,
  `seq` int(11) DEFAULT NULL,
  KEY `name` (`name`,`seq`),
  KEY `seq` (`seq`,`name`),
  CONSTRAINT `c_ibfk_1` FOREIGN KEY (`name`, `seq`) REFERENCES `p` (`name`, `seq`),
  CONSTRAINT `c_ibfk_2` FOREIGN KEY (`seq`, `name`) REFERENCES `p` (`seq`, `name`)
) ENGINE=InnoDB&lt;/pre&gt;

&lt;p&gt;(You can get this situation only if you create corresponding indexes (name,seq) and (seq,name) on the parent table as well of course. I used a primary key for (name,seq) and a unique constraint for (seq,name) to get this effect.)&lt;/p&gt;

&lt;p&gt;Now that's what I would call duplicate foreign keys - there really is no functional difference between these foreign key definitions (but there is for the aforementioned cases): they impose identical restrictions on the allowed input in the (name,seq) columns. &lt;/p&gt;

&lt;p&gt;Of course, the involved indexes are not equivalent, and arguably not duplicates (because they potentially lead to different query execution plans).&lt;/p&gt;</description>
		<content:encoded><![CDATA[<p>Hi Xaprb/Baron,</p>
<p>Great tool. I have a question though. I was wondering why the project appears as &#8220;Duplicate index/foreign key finder&#8221; on MySQLForge.</p>
<p>I really know next to nothing about perl so I might miss an important point by not understanding the code, but it seems to me that if this script really compares the strings from the <code>SHOW CREATE TABLE</code> output like described above, it can in no way spot all duplicate or redundant foreign key definitions.</p>
<p>It depends on what you call a duplicate foreign key of course. I mean, suppose the (innoDB) parent table would have an index on (col1,col2) then I can create two foreign key constraints in the child table, one that references just (col1), and one that references (col1,col2). I suppose the script would catch these cases. However, I would not call those &#8216;duplicate&#8217; foreign keys. I would prefer &#8217;spurious&#8217; or &#8216;redundant&#8217;. Take a look at this example:</p>
<pre>CREATE TABLE `c` (
  `name` varchar(10) DEFAULT NULL,
  `seq` int(11) DEFAULT NULL,
  KEY `name` (`name`,`seq`),
  KEY `seq` (`seq`,`name`),
  CONSTRAINT `c_ibfk_1` FOREIGN KEY (`name`, `seq`) REFERENCES `p` (`name`, `seq`),
  CONSTRAINT `c_ibfk_2` FOREIGN KEY (`seq`, `name`) REFERENCES `p` (`seq`, `name`)
) ENGINE=InnoDB</pre>
<p>(You can get this situation only if you create corresponding indexes (name,seq) and (seq,name) on the parent table as well of course. I used a primary key for (name,seq) and a unique constraint for (seq,name) to get this effect.)</p>
<p>Now that&#8217;s what I would call duplicate foreign keys - there really is no functional difference between these foreign key definitions (but there is for the aforementioned cases): they impose identical restrictions on the allowed input in the (name,seq) columns. </p>
<p>Of course, the involved indexes are not equivalent, and arguably not duplicates (because they potentially lead to different query execution plans).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dmitri Mikhailov</title>
		<link>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-1728</link>
		<author>Dmitri Mikhailov</author>
		<pubDate>Fri, 08 Sep 2006 18:56:51 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-1728</guid>
		<description>&lt;p&gt;Nice tool, thanks.&lt;/p&gt;

&lt;p&gt;A little touch: it makes sense to process different types of indexes, full-text indexes in particular, separately.&lt;/p&gt;

&lt;p&gt;For example, a complex full-text index cannot replace a simple index:&lt;/p&gt;

&lt;pre&gt;create table user
(
  user_id    bigint(20) not null auto_increment
, first_name    varchar(32) not null default ''
, last_name    varchar(32) not null default ''
, email    varchar(64) not null default ''
...
, primary key user_pk (user_id)
, key user_last_name_i (last_name)
, fulltext key user_name_email_ft (last_name, first_name, email)
...
)&lt;/pre&gt;

&lt;p&gt;Script output:&lt;/p&gt;

&lt;pre&gt;Table test.user has possible duplicate indexes:
        `last_name`,`first_name',`email`
        `last_name`&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Nice tool, thanks.</p>
<p>A little touch: it makes sense to process different types of indexes, full-text indexes in particular, separately.</p>
<p>For example, a complex full-text index cannot replace a simple index:</p>
<pre>create table user
(
  user_id    bigint(20) not null auto_increment
, first_name    varchar(32) not null default ''
, last_name    varchar(32) not null default ''
, email    varchar(64) not null default ''
...
, primary key user_pk (user_id)
, key user_last_name_i (last_name)
, fulltext key user_name_email_ft (last_name, first_name, email)
...
)</pre>
<p>Script output:</p>
<pre>Table test.user has possible duplicate indexes:
        `last_name`,`first_name',`email`
        `last_name`</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Frank Mash</title>
		<link>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-1726</link>
		<author>Frank Mash</author>
		<pubDate>Fri, 08 Sep 2006 14:48:16 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-1726</guid>
		<description>&lt;p&gt;Xaprb,&lt;/p&gt;

&lt;p&gt;Great work man.  Keep it up ;)&lt;/p&gt;

&lt;p&gt;Frank&lt;/p&gt;</description>
		<content:encoded><![CDATA[<p>Xaprb,</p>
<p>Great work man.  Keep it up ;)</p>
<p>Frank</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Xaprb</title>
		<link>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-1721</link>
		<author>Xaprb</author>
		<pubDate>Fri, 08 Sep 2006 02:14:21 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/08/28/how-to-find-duplicate-and-redundant-indexes-in-mysql/#comment-1721</guid>
		<description>&lt;p&gt;Yeah, I'm adding it to forge, but it doesn't feel right to add it to innotop, because innotop is about monitoring, not 'static analysis' or whatever you'd call this.&lt;/p&gt;</description>
		<content:encoded><![CDATA[<p>Yeah, I&#8217;m adding it to forge, but it doesn&#8217;t feel right to add it to innotop, because innotop is about monitoring, not &#8217;static analysis&#8217; or whatever you&#8217;d call this.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
