﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-踏踏实实做人，勤勤肯肯做事</title><link>http://www.blogjava.net/tmdqn119/</link><description /><language>zh-cn</language><lastBuildDate>Sat, 18 Apr 2026 11:10:59 GMT</lastBuildDate><pubDate>Sat, 18 Apr 2026 11:10:59 GMT</pubDate><ttl>60</ttl><item><title>[转载]建立正确合理的MYSQL数据库索引(下)</title><link>http://www.blogjava.net/tmdqn119/archive/2007/09/22/147492.html</link><dc:creator>擦肩而过</dc:creator><author>擦肩而过</author><pubDate>Sat, 22 Sep 2007 15:19:00 GMT</pubDate><guid>http://www.blogjava.net/tmdqn119/archive/2007/09/22/147492.html</guid><wfw:comment>http://www.blogjava.net/tmdqn119/comments/147492.html</wfw:comment><comments>http://www.blogjava.net/tmdqn119/archive/2007/09/22/147492.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tmdqn119/comments/commentRss/147492.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tmdqn119/services/trackbacks/147492.html</trackback:ping><description><![CDATA[<p style="margin-left: 21pt"><span>用一个例子详细说明单列索引与组合索引的区别及索引使用中的一些细节</span></p>
<p style="margin-left: 21pt"><span>建一个表：</span><span><br />
CREATE TABLE myIndex ( </span></p>
<p style="margin-left: 21pt"><span>i_testID INT NOT NULL AUTO_INCREMENT, </span></p>
<p style="margin-left: 21pt"><span>vc_Name VARCHAR(50) NOT NULL, </span></p>
<p style="margin-left: 21pt"><span>vc_City VARCHAR(50) NOT NULL,</span></p>
<p style="margin-left: 21pt"><span>i_Age INT NOT NULL,</span></p>
<p style="margin-left: 21pt"><span>i_SchoolID INT NOT NULL, </span></p>
<p style="margin-left: 21pt"><span>PRIMARY KEY (i_testID) </span></p>
<p style="margin-left: 21pt"><span>);</span></p>
<p><span style="font-size: 10.5pt">　　假设这个表中有</span><span style="font-size: 10.5pt">10000</span><span style="font-size: 10.5pt">条记录，其中很分散地</span><span style="font-size: 10.5pt">分布了</span><span style="font-size: 10.5pt">5</span><span style="font-size: 10.5pt">条</span><span style="font-size: 10.5pt">vc_Name="erquan"</span><span style="font-size: 10.5pt">的记录，只不过</span><span style="font-size: 10.5pt">city,age,school</span><span style="font-size: 10.5pt">的组合各不相同。</span><span style="font-size: 10.5pt"><br />
&nbsp;&nbsp;</span><span style="font-size: 10.5pt">来看这条</span><span style="font-size: 10.5pt">T-SQL</span><span style="font-size: 10.5pt">：</span><span style="font-size: 10.5pt"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT i_testID FROM myIndex WHERE vc_Name='erquan' AND vc_City='beijing</span><span style="font-size: 10.5pt">' AND i_Age=25;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10.5pt">首先考虑建单列索引：</span><span style="font-size: 10.5pt"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10.5pt">在</span><span style="font-size: 10.5pt">vc_Name</span><span style="font-size: 10.5pt">列上建立了索引。执行</span><span style="font-size: 10.5pt">T-SQL</span><span style="font-size: 10.5pt">时，</span><span style="font-size: 10.5pt">MYSQL</span><span style="font-size: 10.5pt">很快将目标锁定在了</span><span style="font-size: 10.5pt">vc_Name=erquan</span><span style="font-size: 10.5pt">的</span><span style="font-size: 10.5pt">5</span><span style="font-size: 10.5pt">条记录上，取出来放到一中间</span><span style="font-size: 10.5pt"> </span><span style="font-size: 10.5pt">结果集。在这个结果集里，先排除掉</span><span style="font-size: 10.5pt">vc_City</span><span style="font-size: 10.5pt">不等于</span><span style="font-size: 10.5pt">"beijing</span><span style="font-size: 10.5pt">"</span><span style="font-size: 10.5pt">的记录，再排除</span><span style="font-size: 10.5pt">i_Age</span><span style="font-size: 10.5pt">不等于</span><span style="font-size: 10.5pt">25</span><span style="font-size: 10.5pt">的记录，最后筛选出唯一的符合条件的记录。</span><span style="font-size: 10.5pt"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10.5pt">虽然在</span><span style="font-size: 10.5pt">vc_Name</span><span style="font-size: 10.5pt">上建立了索引，查询时</span><span style="font-size: 10.5pt">MYSQL</span><span style="font-size: 10.5pt">不用扫描整张表，效率有所提高，但离我们的要求还有一定的距离。同样的，在</span><span style="font-size: 10.5pt">vc_City</span><span style="font-size: 10.5pt">和</span><span style="font-size: 10.5pt">i_Age</span><span style="font-size: 10.5pt">分别建立的单列索引的效率相似。</span><span style="font-size: 10.5pt"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10.5pt">为了进一步榨取</span><span style="font-size: 10.5pt">MySQL</span><span style="font-size: 10.5pt">的效率，就要考虑建立组合索引。就是将</span><span style="font-size: 10.5pt">vc_Name,vc_City,i_Age</span><span style="font-size: 10.5pt">建到一个索引里：</span><span style="font-size: 10.5pt"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ALTER TABLE myIndex ADD INDEX name_city_age (vc_Name(10),vc_City,i_Age);--</span><span style="font-size: 10.5pt">注意了，建表时，</span><span style="font-size: 10.5pt">vc_Name</span><span style="font-size: 10.5pt">长度为</span><span style="font-size: 10.5pt">50</span><span style="font-size: 10.5pt">，这里为什么用</span><span style="font-size: 10.5pt">10</span><span style="font-size: 10.5pt">呢？因为一般情况下名字的长</span><span style="font-size: 10.5pt"> </span><span style="font-size: 10.5pt">度不会超过</span><span style="font-size: 10.5pt">10</span><span style="font-size: 10.5pt">，这样会加速索引查询速度，还会减少索引文件的大小，提高</span><span style="font-size: 10.5pt">INSERT</span><span style="font-size: 10.5pt">的更新速度。</span><span style="font-size: 10.5pt"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10.5pt">执行</span><span style="font-size: 10.5pt">T-SQL</span><span style="font-size: 10.5pt">时，</span><span style="font-size: 10.5pt">MySQL</span><span style="font-size: 10.5pt">无须扫描任何记录就到找到唯一的记录！</span><span style="font-size: 10.5pt"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10.5pt">肯定有人要问了，如果分别在</span><span style="font-size: 10.5pt">vc_Name,vc_City,i_Age</span><span style="font-size: 10.5pt">上建立单列索引，让该表有</span><span style="font-size: 10.5pt">3</span><span style="font-size: 10.5pt">个单列索引，查询时和上述的组合索引效率一样</span><span style="font-size: 10.5pt"> </span><span style="font-size: 10.5pt">吧？嘿嘿，大不一样，远远低于我们的组合索引</span><span style="font-size: 10.5pt">~~</span><span style="font-size: 10.5pt">虽然此时有了三个索引，但</span><span style="font-size: 10.5pt">MySQL</span><span style="font-size: 10.5pt">只能用到其中的那个它认为似乎是最有效率的单列索引。</span><span style="font-size: 10.5pt"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10.5pt">建立这样的组合索引，其实是相当于分别建立了</span><span style="font-size: 10.5pt"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vc_Name,vc_City,i_Age<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vc_Name,vc_City<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vc_Name<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10.5pt">这样的三个组合索引为什么没有</span><span style="font-size: 10.5pt">vc_City,i_Age</span><span style="font-size: 10.5pt">等这样的组合索引的效率呢？这是因为</span><span style="font-size: 10.5pt">mysql</span><span style="font-size: 10.5pt">组合索引</span><span style="font-size: 10.5pt">"</span><span style="font-size: 10.5pt">最左前缀</span><span style="font-size: 10.5pt">"</span><span style="font-size: 10.5pt">的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这三列的查询都会用到该组合索引，下面的几个</span><span style="font-size: 10.5pt">T-SQL</span><span style="font-size: 10.5pt">会用到：</span><span style="font-size: 10.5pt"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * FROM myIndex WHREE vc_Name="erquan" AND vc_City="beijing</span><span style="font-size: 10.5pt">"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * FROM myIndex WHREE vc_Name="erquan"<br />
</span><span style="font-size: 10.5pt">而下面几个则不会用到：</span><span style="font-size: 10.5pt"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * FROM myIndex WHREE i_Age=20 AND vc_City="beijing</span><span style="font-size: 10.5pt">"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * FROM myIndex WHREE vc_City="beijing</span><span style="font-size: 10.5pt">"</span></p>
<p><span style="font-size: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 但什么情况下需要建立索引呢？一般来说，在WHERE和JOIN中出现的列需要建立索引，但也不完全如此，因为MySQL只对 &lt;，&lt;=，=，&gt;，&gt;=，BETWEEN，IN，以及某些时候的LIKE才会使用索引。<br />
SELECT t.vc_Name FROM testIndex t LEFT JOIN myIndex m ON t.vc_Name=m.vc_Name WHERE m.i_Age=20 AND m.vc_City='beijing' 时，有对myIndex表的vc_City和i_Age建立索引的需要，由于testIndex表的vc_Name开出现在了JOIN子句中，也有对它建立索引的必要。<br />
<br />
　　刚才提到只有某些时候的LIKE才需建立索引？是的。因为在以通配符 % 和 _ 开头作查询时，MySQL不会使用索引，如<br />
SELECT * FROM myIndex WHERE vc_Name like'erquan%'<br />
会使用索引，而<br />
SELECT * FROM myIndex WHEREt vc_Name like'%erquan'<br />
就不会使用索引了。<br />
</span></p>
<img src ="http://www.blogjava.net/tmdqn119/aggbug/147492.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tmdqn119/" target="_blank">擦肩而过</a> 2007-09-22 23:19 <a href="http://www.blogjava.net/tmdqn119/archive/2007/09/22/147492.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]建立正确合理的MYSQL数据库索引(上)</title><link>http://www.blogjava.net/tmdqn119/archive/2007/09/22/147490.html</link><dc:creator>擦肩而过</dc:creator><author>擦肩而过</author><pubDate>Sat, 22 Sep 2007 15:18:00 GMT</pubDate><guid>http://www.blogjava.net/tmdqn119/archive/2007/09/22/147490.html</guid><wfw:comment>http://www.blogjava.net/tmdqn119/comments/147490.html</wfw:comment><comments>http://www.blogjava.net/tmdqn119/archive/2007/09/22/147490.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tmdqn119/comments/commentRss/147490.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tmdqn119/services/trackbacks/147490.html</trackback:ping><description><![CDATA[<p style="text-indent: 21pt" align="left"><span style="font-size: 10.5pt"></span><span style="font-size: 10.5pt">普通</span><span style="font-size: 10.5pt">MySQL</span><span style="font-size: 10.5pt">运行，数据量和访问量不大的话，是足够快的，但是当数据量和访问量剧增的时候，那么就会明显发现</span><span style="font-size: 10.5pt">MySQL</span><span style="font-size: 10.5pt">很慢，甚至</span><span style="font-size: 10.5pt">down</span><span style="font-size: 10.5pt">掉，那么就要考虑优化我们的</span><span style="font-size: 10.5pt">MySQL</span><span style="font-size: 10.5pt">了，其中优化</span><span style="font-size: 10.5pt">MYSQL</span><span style="font-size: 10.5pt">的一个重要环节就是为数据库建立正确合理的索引。</span></p>
<p style="text-indent: 21pt">如果没有索引，执行查询时<span>MySQL</span>必须从第一个记录开始扫描整个表的所有记录，直至找到符合要求的记录。表里面的记录数量越多，这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引，<span>MySQL</span>无需扫描任何记录即可迅速得到目标记录所在的位置。也就是说索引可以大大减少数据库管理系统查找数据的时间。<span style="font-size: 14pt; line-height: 173%">索引有哪些优点？</span></p>
<p style="margin-left: 35.95pt; text-indent: -18pt"><span><span>1、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;</span></span></span><span>通过创建唯一性索引，可以保证数据库表中每一行数据的唯一性。</span></p>
<p style="margin-left: 35.95pt; text-indent: -18pt"><span><span>2、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;</span></span></span><span>可以大大加快数据的检索速度，这也是创建索引的最主要原因。</span></p>
<p style="margin-left: 35.95pt; text-indent: -18pt"><span><span>3、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;</span></span></span><span>可以加速表和表之间的连接，这在实现数据的参考完整性方面特别有意义。</span></p>
<p style="margin-left: 35.95pt; text-indent: -18pt"><span><span>4、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;</span></span></span><span>在使用分组和排序子句进行数据检索时，同样可以显著减少查询中分组和排序的时间。</span></p>
<h3><span style="font-size: 14pt; line-height: 173%">　索引有哪些缺点？</span></h3>
<p style="margin-left: 35.95pt; text-indent: -18pt"><span><span>1、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;</span></span></span><span>创建索引和维护索引要耗费时间，这种时间随着数据量的增加而增加。</span></p>
<p style="margin-left: 35.95pt; text-indent: -18pt"><span><span>2、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;</span></span></span><span>除了数据表占数据空间之外，每一个索引还要占一定的物理空间，如果要建立聚簇索引，需要的空间就会更大。</span></p>
<p style="margin-left: 35.95pt; text-indent: -18pt"><span><span>3、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;</span></span></span><span>当对表中的数据进行增加、删除和修改的时候，索引也要动态的维护，这样就降低了数据的维护速度。</span></p>
<h3><span style="font-size: 14pt; line-height: 173%">　索引有哪些类型？</span></h3>
<p style="margin-left: 39pt; text-indent: -18pt"><strong><span><span>1、<span style="font: 7pt Times New Roman"> </span></span></span></strong><strong><span>普通索引</span></strong></p>
<p style="margin-left: 21pt"><span>这是最基本的索引类型，而且它没有唯一性之类的限制。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt"><strong><span><span>2、<span style="font: 7pt Times New Roman"> </span></span></span></strong><strong><span>唯一性索引</span></strong></p>
<p style="margin-left: 21pt"><span>这种索引和前面的</span><span>&#8220;</span><span>普通索引</span><span>&#8221;</span><span>基本相同，但有一个区别：索引列的所有值都只能出现一次，即必须唯一。</span></p>
<p style="margin-left: 21pt"><strong><span>3</span></strong><strong><span>、主键</span></strong></p>
<p style="text-indent: 17.95pt"><span>它是一种特殊的唯一索引，不允许有空值。</span></p>
<p style="margin-left: 17.95pt"><strong><span>4</span></strong><strong><span>、全文索引</span></strong></p>
<p style="margin-left: 17.95pt"><span>MySQL</span><span>从</span><ST1:CHSDATE year="1899" month="12" day="30" islunardate="False" isrocdate="False"><span>3.23.23</span></ST1:CHSDATE><span>版开始支持全文索引和全文检索。</span></p>
<h3><span style="font-size: 14pt; line-height: 173%">　单列索引和组合索引：</span></h3>
<p style="text-indent: 17.95pt"><span>单列索引就是把索引单独建立在一个字段上。</span></p>
<p style="text-indent: 17.95pt"><span>组合索引复合索引就是一个索引创建在两个列或者多个列上。在搜索时，当两个或者多个列作为一个关键值时，最好在这些列上创建复合索引。</span></p>
<h3><span style="font-size: 14pt; line-height: 173%">　建立和使用索引有哪些注意事项：</span></h3>
<p style="margin-left: 50.2pt; text-indent: -32.25pt"><span><span>1、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span><span>索引要建立在经常进行</span><span>select</span><span>操作的字段上</span><span>。</span><span>这是因为，如果这些列很少用到，那么有无索引并不能明显改变查询速度。相反，由于增加了索引，反而降低了系统的维护速度和增大了空间需求。</span></p>
<p style="margin-left: 50.2pt; text-indent: -32.25pt"><span><span>2、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span><span>索引要建立在值比较唯一的字段上。这样做才是发挥索引的最大效果。</span><span style="font-size: 6pt">，</span><span>比如主键的</span><span>id</span><span>字段，唯一的名字</span><span>name</span><span>字段等等。如果索引建立在唯一值比较少的字段，比如性别</span><span>gender</span><span>字段，寥寥无几的类别字段等，刚索引几乎没有任何意义。</span></p>
<p style="margin-left: 50.2pt; text-indent: -32.25pt"><span><span>3、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span><span>对于那些定义为</span><span>text</span><span>、</span><span> image</span><span>和</span><span>bit</span><span>数据类型的列不应该增加索引。因为这些列的数据量要么相当大，要么取值很少。</span></p>
<p style="margin-left: 50.2pt; text-indent: -32.25pt"><span><span>4、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span><span>当修改性能远远大于检索性能时，不应该创建索引。修改性能和检索性能是互相矛盾的。当增加索引时，会提高检索性能，但是会降低修改性能。当减少索引时，会提高修改性能，降低检索性能。因此，当修改性能远远大于检索性能时，不应该创建索引。</span></p>
<p style="margin-left: 50.2pt; text-indent: -32.25pt"><span><span>5、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span><span>在</span><span>WHERE</span><span>和</span><span>JOIN</span><span>中出现的列需要建立索引。</span></p>
<p style="margin-left: 50.2pt; text-indent: -32.25pt"><span><span>6、<span style="font: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span><span>在以通配符</span><span> % </span><span>和</span><span> _ </span><span>开头作查询时，</span><span>MySQL</span><span>索引是无效的。但是</span><span>这样索引是有效的：</span><span>select * from tbl1 where name like 'xxx%'</span><span>，所以谨慎的写你的</span><span>SQL</span><span>是很重要的。</span></p>
<img src ="http://www.blogjava.net/tmdqn119/aggbug/147490.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tmdqn119/" target="_blank">擦肩而过</a> 2007-09-22 23:18 <a href="http://www.blogjava.net/tmdqn119/archive/2007/09/22/147490.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>