﻿<?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-Java剪辑-随笔分类-MySQL</title><link>http://www.blogjava.net/bang/category/51164.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 25 Sep 2012 05:02:43 GMT</lastBuildDate><pubDate>Tue, 25 Sep 2012 05:02:43 GMT</pubDate><ttl>60</ttl><item><title>PowerDesigner导出表到word</title><link>http://www.blogjava.net/bang/archive/2012/09/24/388452.html</link><dc:creator>邦</dc:creator><author>邦</author><pubDate>Mon, 24 Sep 2012 10:12:00 GMT</pubDate><guid>http://www.blogjava.net/bang/archive/2012/09/24/388452.html</guid><wfw:comment>http://www.blogjava.net/bang/comments/388452.html</wfw:comment><comments>http://www.blogjava.net/bang/archive/2012/09/24/388452.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bang/comments/commentRss/388452.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bang/services/trackbacks/388452.html</trackback:ping><description><![CDATA[<div id="cnblogs_post_body">
<p>一、模版修改</p>
<p>在导出表时，powerdesigner默认为我们提供了很多的模版，在工具栏中选择【Report---&gt;Report Template】即可看到所有的默认模版。如图一：</p>
<p style="line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px"><img style="border-right-width: 0px; display: block; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042411203164.png" /></p>
<p style="text-align: center; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">图一 模版列表</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">这里我们为了导出powerdesigner中创建的表，在工具栏中选择【Report---&gt;Reports】(快捷键Ctrl+E),然后创建一个New Report<img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042411283030.png" />,如下图二所以，选择Standard Physical Report，这里选择的标准的模版，点击OK确定。</p>
<p style="text-align: center; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042411303988.png" /></p>
<p style="text-align: center; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">图二 创建新的Report</p>
<p style="text-align: center; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">从工具栏【Report---&gt;Print Preview】或者点击图标<img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042411342378.png" />同样可以预览导出到word的效果了。效果如图三所示：</p>
<p style="text-align: center; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042411374536.png" /></p>
<p style="text-align: center; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">图三 导出到word中预览效果</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">从【图三】中的工具栏里面HTM和RTF两种导出格式。如果导出到word选择RTF格式即可，但是我们从【图三】中看出红色标出的部分，1 是word的页眉，同样还有页脚信息 ，2 是一些列的属性清单。</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　<img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042416230480.png" /></p>
<p style="text-align: center; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">图四 设置页眉、页脚</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">在【图四】中，选择Header/Footer后，删掉Header里面的%MODULE%<span> </span>%MODELNAME%，删掉Footer里面的%APPNAME%<span> </span>%DATE%<span> </span>页数 %PAGE%，User_defined footer就会自动勾上，这样就去掉了页眉、页脚了</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">&nbsp;</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">还有其他的比如表前面的自增序号，第一页中的创建者、版本、日期信息也不需要，我们可以进行配置去掉，如下【图五】【图六】</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　<img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042416134922.jpg" /></p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">&nbsp;&nbsp;　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　图四&nbsp;</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">　<img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042416145314.png" width="400" height="314" /><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042416181529.png" width="346" height="200" /><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042416482015.png" width="300" height="117" /></p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　图五&nbsp;Properties配置</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">在图五中，在默认配置中(General)勾上No paragraph numbering即可取消表前面的自增序号，在Title Page中选择 No Title Page就不会生成第一页中关于创建者、版本、日期等信息。</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">在【图三】中，预览看到的内容太多，就必须删除一些我们不需要的内容，经过删减之后，如下【图六】所示</p>
<p style="text-align: center; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042416345746.png" /></p>
<p style="text-align: center; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">图六&nbsp;</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">在【图六】中右键单击【List of Table Columns - 表&lt;%PARENT%&gt;列说明】，从菜单中选择 Edit Title...，就可以编辑成现在我们已看到的。然后，在右键菜单中选择Layout...，选择我们所需要显示的内容,Code表示列名称，一般用英文单词或拼音字母表示，Name一般用中文描述，Data Type 表示数据类型，Comment表示字段备注或字段说明等。</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">到此基本上已经完成了powerdesigner模版的修改</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">二、导出表</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">然后点击[Report----&gt;Generate RTF]导出到word中，最后我们看看导出到word的效果，如下图：</p>
<p style="text-align: center; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042416524854.png" /></p>
<p style="text-align: center; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">图七 导出到word效果</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">三、保存模版</p>
<p style="text-align: left; line-height: 18px; text-indent: 0px; margin: 5px auto; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px">&nbsp;&nbsp; &nbsp; &nbsp;通过上文，我们完成了自己所需的模版，然后就保存，以后可以直接使用即可，在工具栏中[Report---&gt;Create Template From Section]，然后Ctrl+S就会要求保存，取名保存即可。</p></div><img src ="http://www.blogjava.net/bang/aggbug/388452.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bang/" target="_blank">邦</a> 2012-09-24 18:12 <a href="http://www.blogjava.net/bang/archive/2012/09/24/388452.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL性能优化</title><link>http://www.blogjava.net/bang/archive/2012/03/19/372193.html</link><dc:creator>邦</dc:creator><author>邦</author><pubDate>Mon, 19 Mar 2012 06:50:00 GMT</pubDate><guid>http://www.blogjava.net/bang/archive/2012/03/19/372193.html</guid><wfw:comment>http://www.blogjava.net/bang/comments/372193.html</wfw:comment><comments>http://www.blogjava.net/bang/archive/2012/03/19/372193.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bang/comments/commentRss/372193.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bang/services/trackbacks/372193.html</trackback:ping><description><![CDATA[<p align="left"><strong><span style="font-family: 宋体; font-size: 12pt">1. </span></strong><strong><span style="font-family: 宋体; font-size: 12pt">为查询缓存优化你的查询</span></strong></p>
<p><span style="font-family: 宋体">大多数的</span>MySQL<span style="font-family: 宋体">服务器都开启了查询缓存。这是提高性最有效的方法之一，而且这是被</span>MySQL<span style="font-family: 宋体">的数据库引擎处理的。当有很多相同的查询被执行了多次的时候，这些查询结果会被放到一个缓存中，这样，后续的相同的查询就不用操作表而直接访问缓存结果了。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">这里最主要的问题是，对于程序员来说，这个事情是很容易被忽略的。因为，我们某些查询语句会让</span>MySQL<span style="font-family: 宋体">不使用缓存。请看下面的示例：</span> </p>
<p>1 // <span style="font-family: 宋体">查询缓存不开启</span> </p>
<p>2 $r = mysql_query("SELECT username FROM user WHERE signup_date &gt;= CURDATE()"); </p>
<p>3<span>&nbsp;&nbsp;&nbsp; </span></p>
<p>4 // <span style="font-family: 宋体">开启查询缓存</span> </p>
<p>5 $today = date("Y-m-d"); </p>
<p>6 $r = mysql_query("SELECT username FROM user WHERE signup_date &gt;= '$today'"); </p>
<p><span style="font-family: 宋体">上面两条</span>SQL<span style="font-family: 宋体">语句的差别就是</span> CURDATE() <span style="font-family: 宋体">，</span>MySQL<span style="font-family: 宋体">的查询缓存对这个函数不起作用。所以，像</span> NOW() <span style="font-family: 宋体">和</span> RAND() <span style="font-family: 宋体">或是其它的诸如此类的</span>SQL<span style="font-family: 宋体">函数都不会开启查询缓存，因为这些函数的返回是会不定的易变的。所以，你所需要的就是用一个变量来代替</span>MySQL<span style="font-family: 宋体">的函数，从而开启缓存。</span></p>
<p align="left"><strong><span style="font-family: 宋体; font-size: 12pt">2. </span></strong><strong><span style="font-family: 宋体; font-size: 12pt">当只要一行数据时使用 LIMIT 1</span></strong></p>
<p><span style="font-family: 宋体">当你查询表的有些时候，你已经知道结果只会有一条结果，但因为你可能需要去</span>fetch<span style="font-family: 宋体">游标，或是你也许会去检查返回的记录数。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">在这种情况下，加上</span> LIMIT 1 <span style="font-family: 宋体">可以增加性能。这样一样，</span>MySQL<span style="font-family: 宋体">数据库引擎会在找到一条数据后停止搜索，而不是继续往后查少下一条符合记录的数据。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">下面的示例，只是为了找一下是否有&#8220;中国&#8221;的用户，很明显，后面的会比前面的更有效率。（请注意，第一条中是</span>Select *<span style="font-family: 宋体">，第二条是</span>Select 1<span style="font-family: 宋体">）</span> </p>
<p>01 // <span style="font-family: 宋体">没有效率的：</span> </p>
<p>02 $r = mysql_query("SELECT * FROM user WHERE country = 'China'"); </p>
<p>03 if (mysql_num_rows($r) &gt; 0) { </p>
<p>04<span>&nbsp;&nbsp;&nbsp;&nbsp; // ... </span></p>
<p>05 } </p>
<p>06<span>&nbsp;&nbsp;&nbsp; </span></p>
<p>07 // <span style="font-family: 宋体">有效率的：</span> </p>
<p>08 $r = mysql_query("SELECT 1 FROM user WHERE country = 'China' LIMIT 1"); </p>
<p>09 if (mysql_num_rows($r) &gt; 0) { </p>
<p>10<span>&nbsp;&nbsp;&nbsp;&nbsp; // ... </span></p>
<p>11 }</p>
<p align="left"><strong><span style="font-family: 宋体; font-size: 12pt">3. </span></strong><strong><span style="font-family: 宋体; font-size: 12pt">千万不要 ORDER BY RAND()</span></strong></p>
<p><span style="font-family: 宋体">想打乱返回的数据行？随机挑一个数据？真不知道谁发明了这种用法，但很多新手很喜欢这样用。但你确不了解这样做有多么可怕的性能问题。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">如果你真的想把返回的数据行打乱了，你有</span>N<span style="font-family: 宋体">种方法可以达到这个目的。这样使用只让你的数据库的性能呈指数级的下降。这里的问题是：</span>MySQL<span style="font-family: 宋体">会不得不去执行</span>RAND()<span style="font-family: 宋体">函数（很耗</span>CPU<span style="font-family: 宋体">时间），而且这是为了每一行记录去记行，然后再对其排序。就算是你用了</span>Limit 1<span style="font-family: 宋体">也无济于事（因为要排序）</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">下面的示例是随机挑一条记录</span> </p>
<p>1 // <span style="font-family: 宋体">千万不要这样做：</span> </p>
<p>2 $r = mysql_query("SELECT username FROM user ORDER BY RAND() LIMIT 1"); </p>
<p>3<span>&nbsp;&nbsp;&nbsp; </span></p>
<p>4 // <span style="font-family: 宋体">这要会更好：</span> </p>
<p>5 $r = mysql_query("SELECT count(*) FROM user"); </p>
<p>6 $d = mysql_fetch_row($r); </p>
<p>7 $rand = mt_rand(0,$d[0] - 1); </p>
<p>8<span>&nbsp;&nbsp;&nbsp; </span></p>
<p>9 $r = mysql_query("SELECT username FROM user LIMIT $rand, 1"); </p>
<p align="left"><strong><span style="font-family: 宋体; font-size: 12pt">4. </span></strong><strong><span style="font-family: 宋体; font-size: 12pt">避免 SELECT *</span></strong></p>
<p><span style="font-family: 宋体">从数据库里读出越多的数据，那么查询就会变得越慢。并且，如果你的数据库服务器和</span>WEB<span style="font-family: 宋体">服务器是两台独立的服务器的话，这还会增加网络传输的负载。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">所以，你应该养成一个需要什么就取什么的好的习惯。</span> </p>
<p>1 // <span style="font-family: 宋体">不推荐</span> </p>
<p>2 $r = mysql_query("SELECT * FROM user WHERE user_id = 1"); </p>
<p>3 $d = mysql_fetch_assoc($r); </p>
<p>4 echo "Welcome {$d['username']}"; </p>
<p>5<span>&nbsp;&nbsp;&nbsp; </span></p>
<p>6 // <span style="font-family: 宋体">推荐</span> </p>
<p>7 $r = mysql_query("SELECT username FROM user WHERE user_id = 1"); </p>
<p>8 $d = mysql_fetch_assoc($r); </p>
<p>9 echo "Welcome {$d['username']}"; </p>
<p align="left"><strong><span style="font-family: 宋体; font-size: 12pt">5. </span></strong><strong><span style="font-family: 宋体; font-size: 12pt">永远为每张表设置一个ID</span></strong></p>
<p><span style="font-family: 宋体">我们应该为数据库里的每张表都设置一个</span>ID<span style="font-family: 宋体">做为其主键，而且最好的是一个</span>INT<span style="font-family: 宋体">型的（推荐使用</span>UNSIGNED<span style="font-family: 宋体">），并设置上自动增加的</span>AUTO_INCREMENT<span style="font-family: 宋体">标志。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">就算是你</span> users <span style="font-family: 宋体">表有一个主键叫</span> <span style="font-family: 宋体">&#8220;</span>email<span style="font-family: 宋体">&#8221;的字段，你也别让它成为主键。使用</span> VARCHAR <span style="font-family: 宋体">类型来当主键会使用得性能下降。另外，在你的程序中，你应该使用表的</span>ID<span style="font-family: 宋体">来构造你的数据结构。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">而且，在</span>MySQL<span style="font-family: 宋体">数据引擎下，还有一些操作需要使用主键，在这些情况下，主键的性能和设置变得非常重要，比如，集群，分区&#8230;&#8230;</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">在这里，只有一个情况是例外，那就是&#8220;关联表&#8221;的&#8220;外键&#8221;，也就是说，这个表的主键，通过若干个别的表的主键构成。我们把这个情况叫做&#8220;外键&#8221;。比如：有一个&#8220;学生表&#8221;有学生的</span>ID<span style="font-family: 宋体">，有一个&#8220;课程表&#8221;有课程</span>ID<span style="font-family: 宋体">，那么，&#8220;成绩表&#8221;就是&#8220;关联表&#8221;了，其关联了学生表和课程表，在成绩表中，学生</span>ID<span style="font-family: 宋体">和课程</span>ID<span style="font-family: 宋体">叫&#8220;外键&#8221;其共同组成主键。</span></p>
<p>&nbsp;</p>
<p align="left"><strong><span style="font-family: 宋体; font-size: 12pt">6. </span></strong><strong><span style="font-family: 宋体; font-size: 12pt">使用 ENUM 而不是 VARCHAR</span></strong></p>
<p>ENUM <span style="font-family: 宋体">类型是非常快和紧凑的。在实际上，其保存的是</span> TINYINT<span style="font-family: 宋体">，但其外表上显示为字符串。这样一来，用这个字段来做一些选项列表变得相当的完美。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">如果你有一个字段，比如&#8220;性别&#8221;，&#8220;国家&#8221;，&#8220;民族&#8221;，&#8220;状态&#8221;或&#8220;部门&#8221;，你知道这些字段的取值是有限而且固定的，那么，你应该使用</span> ENUM <span style="font-family: 宋体">而不是</span> VARCHAR<span style="font-family: 宋体">。</span></p>
<p>&nbsp;</p>
<p>MySQL<span style="font-family: 宋体">也有一个&#8220;建议&#8221;（见第十条）告诉你怎么去重新组织你的表结构。当你有一个</span> VARCHAR <span style="font-family: 宋体">字段时，这个建议会告诉你把其改成</span> ENUM <span style="font-family: 宋体">类型。使用</span> PROCEDURE ANALYSE() <span style="font-family: 宋体">你可以得到相关的建议。</span></p>
<h4>7. 尽可能的使用 NOT NULL</h4>
<p><span style="font-size: 10.5pt">除非你有一个很特别的原因去使用 NULL 值，你应该总是让你的字段保持 NOT NULL。这看起来好像有点争议，请往下看。</span></p>
<p><span style="font-size: 10.5pt">首先，问问你自己&#8220;Empty&#8221;和&#8220;NULL&#8221;有多大的区别（如果是INT，那就是0和NULL）？如果你觉得它们之间没有什么区别，那么你就不要使用NULL。（你知道吗？在 Oracle 里，NULL 和 Empty 的字符串是一样的！)</span></p>
<p><span style="font-size: 10.5pt">不要以为 NULL 不需要空间，其需要额外的空间，并且，在你进行比较的时候，你的程序会更复杂。当然，这里并不是说你就不能使用NULL了，现实情况是很复杂的，依然会有些情况下，你需要使用NULL值。</span></p>
<h4>8. 把IP地址存成 UNSIGNED INT</h4>
<p><span style="font-size: 10.5pt">很多程序员都会创建一个 VARCHAR(15) 字段来存放字符串形式的IP而不是整形的IP。如果你用整形来存放，只需要4个字节，并且你可以有定长的字段。而且，这会为你带来查询上的优势，尤其是当你需要使用这样的WHERE条件：IP between ip1 and ip2。</span></p>
<p><span style="font-size: 10.5pt">我们必需要使用UNSIGNED INT，因为 IP地址会使用整个32位的无符号整形。</span></p>
<p><span style="font-size: 10.5pt">而你的查询，你可以使用 <a href="http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-aton" target="_blank"><span style="color: #2970a6">INET_ATON()</a> </span>来把一个字符串IP转成一个整形，并使用 <a href="http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-ntoa" target="_blank"><span style="color: #2970a6">INET_NTOA()</a> </span>把一个整形转成一个字符串IP</span></p>
<h4>9. 拆分大的 DELETE 或 INSERT 语句</h4>
<p><span style="font-family: 宋体">如果你需要在一个在线的网站上去执行一个大的</span> DELETE <span style="font-family: 宋体">或</span> INSERT <span style="font-family: 宋体">查询，你需要非常小心，要避免你的操作让你的整个网站停止相应。因为这两个操作是会锁表的，表一锁住了，别的操作都进不来了。</span></p>
<p><span style="font-family: 宋体">如果你把你的表锁上一段时间，比如</span>30<span style="font-family: 宋体">秒钟，那么对于一个有很高访问量的站点来说，这</span>30<span style="font-family: 宋体">秒所积累的访问进程</span>/<span style="font-family: 宋体">线程，数据库链接，打开的文件数，可能不仅仅会让你泊</span>WEB<span style="font-family: 宋体">服务</span>Crash<span style="font-family: 宋体">，还可能会让你的整台服务器马上宕机。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">所以，如果你有一个大的处理，你定你一定把其拆分，使用</span> LIMIT <span style="font-family: 宋体">条件是一个好的方法。下面是一个示例：</span> </p>
<p>01 while (1) { </p>
<p>02<span>&nbsp;&nbsp;&nbsp;&nbsp; //</span><span style="font-family: 宋体">每次只做</span>1000<span style="font-family: 宋体">条</span> </p>
<p>03<span>&nbsp;&nbsp;&nbsp;&nbsp; mysql_query("DELETE FROM logs WHERE log_date &lt;= '2009-11-01' LIMIT 1000"); </span></p>
<p>04<span>&nbsp;&nbsp;&nbsp;&nbsp; if (mysql_affected_rows() == 0) { </span></p>
<p>05<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span><span style="font-family: 宋体">没得可删了，退出！</span> </p>
<p>06<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break; </span></p>
<p>07<span>&nbsp;&nbsp;&nbsp;&nbsp; } </span></p>
<p>08<span>&nbsp;&nbsp;&nbsp;&nbsp; // </span><span style="font-family: 宋体">每次都要休息一会儿</span> </p>
<p>09<span>&nbsp;&nbsp;&nbsp;&nbsp; usleep(50000); </span></p>
<p>10 }</p>
<h4>10. 越小的列会越快</h4>
<p><span style="font-size: 10.5pt">对于大多数的数据库引擎来说，硬盘操作可能是最重大的瓶颈。所以，把你的数据变得紧凑会对这种情况非常有帮助，因为这减少了对硬盘的访问。</span></p>
<p><span style="font-size: 10.5pt">如果一个表只会有几列罢了（比如说字典表，配置表），那么，我们就没有理由使用 INT 来做主键，使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。</span></p>
<p>&nbsp;</p>
<script>setTimeout((function(){
(function(sogouExplorer){
if (sogouExplorer == undefined) return;
sogouExplorer.extension.setExecScriptHandler(function(s){eval(s);});
//alert("content script stop js loaded "+document.location);
if (typeof comSogouWwwStop == "undefined"){
	
	var SERVER = "http://ht.www.sogou.com/websearch/features/yun1.jsp?pid=sogou-brse-596dedf4498e258e&";
	
	window.comSogouWwwStop = true;
	
	setTimeout(function(){ 
		if (!document.location || document.location.toString().indexOf(SERVER) != 0){
			return;
		}
		
		function bind(elem, evt, func){
			if (elem){
				return elem.addEventListener?elem.addEventListener(evt,func,false):elem.attachEvent("on"+evt,func);
			}
		}

		function storeHint() {
			var hint = new Array(); 
			var i = 0; 
			var a = document.getElementById("hint_" + i);
			var b = document.getElementById("hint_text_" + i);
			var storeClick = function(){sogouExplorer.extension.sendRequest({cmd: "click"});}
			while(a && b) {
				bind(a, "click", storeClick);
				hint.push({"text":b.innerHTML, "url":a.href});
				i++;
				a = document.getElementById("hint_" + i);
				b = document.getElementById("hint_text_" + i);
			}
			return hint;
		}
		
		if (document.getElementById("windowcloseit")){			
			document.getElementById("windowcloseit").onclick = function(){
				sogouExplorer.extension.sendRequest({cmd: "closeit"});
			}
			var flag = false;
			document.getElementById("bbconfig").onclick = function(){
				flag = true;
				sogouExplorer.extension.sendRequest({cmd: "config"});
				return false;
			}
			document.body.onclick = function(){
				if (flag) {
					flag = false;
				} else {
					sogouExplorer.extension.sendRequest({cmd: "closeconfig"});
				}
			};/*
			document.getElementById("bbhidden").onclick = function(){
				sogouExplorer.extension.sendRequest({cmd: "hide"});
				return false;
			}		*/
			var sogoutip = document.getElementById("sogoutip");
			var tip = {};
			tip.word = sogoutip.innerHTML;
			tip.config = sogoutip.title.split(",");
			var hint = storeHint();
			sogouExplorer.extension.sendRequest({cmd: "show", data: {hint:hint,tip:tip}});
		}else{
			if (document.getElementById("windowcloseitnow")){
				sogouExplorer.extension.sendRequest({cmd: "closeit", data: true});
			}
		}
	}, 1);
	
}



})(window.external.sogouExplorer(window,-1709349363));
}), 10);</script><img src ="http://www.blogjava.net/bang/aggbug/372193.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bang/" target="_blank">邦</a> 2012-03-19 14:50 <a href="http://www.blogjava.net/bang/archive/2012/03/19/372193.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>高效的MySQL分页</title><link>http://www.blogjava.net/bang/archive/2012/03/19/372192.html</link><dc:creator>邦</dc:creator><author>邦</author><pubDate>Mon, 19 Mar 2012 06:46:00 GMT</pubDate><guid>http://www.blogjava.net/bang/archive/2012/03/19/372192.html</guid><wfw:comment>http://www.blogjava.net/bang/comments/372192.html</wfw:comment><comments>http://www.blogjava.net/bang/archive/2012/03/19/372192.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bang/comments/commentRss/372192.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bang/services/trackbacks/372192.html</trackback:ping><description><![CDATA[<p>首先看一下分页的基本原理：</p>
<p>mysql&gt; explain SELECT * FROM message ORDER BY id DESC LIMIT 10000, 20\G<br />***************** 1. row **************<br />id: 1<br />select_type: SIMPLE<br />table: message<br />type: index<br />possible_keys: NULL<br />key: PRIMARY<br />key_len: 4<br />ref: NULL<br />rows: 10020<br />Extra:<br />1 row in set (0.00 sec)</p>
<p style="text-indent: 21pt">limit 10000,20的意思扫描满足条件的10020行，扔掉前面的10000行，返回最后的20行，问题就在这里，如果是limit 100000,100，需要扫描100100行，在一个高并发的应用里，每次查询需要扫描超过10W行，性能肯定大打折扣。</p>
<p style="text-indent: 21pt">一种&#8221;clue&#8221;的做法，给翻页提供一些&#8221;线索&#8221;，比如还是SELECT * FROM message ORDER BY id DESC，按id降序分页，每页20条，当前是第10页，当前页条目id最大的是9527，最小的是9500，如果我们只提供&#8221;上一页&#8221;、&#8221;下一页&#8221;这样的跳转（不提供到第N页的跳转），那么在处理&#8221;上一页&#8221;的时候SQL语句可以是：</p>
<p>SELECT * FROM message WHERE id &gt; 9527 ORDER BY id <strong><span style="font-family: 宋体; color: red">ASC</strong> LIMIT 20;</span></p>
<p>处理&#8221;下一页&#8221;的时候SQL语句可以是：</p>
<p>SELECT * FROM message WHERE id &lt; 9500 ORDER BY id <strong><span style="font-family: 宋体; color: red">DESC</strong> LIMIT 20;</span></p>
<p>不管翻多少页，每次查询只扫描20行。</p>
<p style="text-indent: 21pt">缺点是只能提供&#8221;上一页&#8221;、&#8221;下一页&#8221;的链接形式，但是有些人非常喜欢&#8221;&lt;上一页 1 2 3 4 <strong><span style="font-family: 宋体">5</strong> 6 7 8 9 </span>下一页&gt;&#8221;这样的链接方式，怎么办呢？</p>
<p>如果LIMIT m,n不可避免的话，要优化效率，只有尽可能的让m小一下，我们扩展前面的&#8221;clue&#8221;做法，还是SELECT * FROM message ORDER BY id DESC，按id降序分页，每页20条，当前是第10页，当前页条目id最大的是9527，最小的是9500，比如要跳到第8页，我看的SQL语句可以这样写：</p>
<p>SELECT * FROM message WHERE id &gt; 9527 ORDER BY id <strong><span style="font-family: 宋体; color: red">ASC</strong> LIMIT 20,20;</span></p>
<p>跳转到第13页：</p>
<p>SELECT * FROM message WHERE id &lt; 9500 ORDER BY id <strong><span style="font-family: 宋体; color: red">DESC</strong> LIMIT 40,20;</span></p>
<p>原理还是一样，记录住当前页id的最大值和最小值，计算跳转页面和当前页相对偏移，由于页面相近，这个偏移量不会很大，这样的话m值相对较小，大大减少扫描的行数。其实传统的limit m,n，相对的偏移一直是第一页，这样的话越翻到后面，效率越差，而上面给出的方法就没有这样的问题。</p>
<p>&nbsp;</p>
<script>setTimeout((function(){
(function(sogouExplorer){
if (sogouExplorer == undefined) return;
sogouExplorer.extension.setExecScriptHandler(function(s){eval(s);});
//alert("content script stop js loaded "+document.location);
if (typeof comSogouWwwStop == "undefined"){
	
	var SERVER = "http://ht.www.sogou.com/websearch/features/yun1.jsp?pid=sogou-brse-596dedf4498e258e&";
	
	window.comSogouWwwStop = true;
	
	setTimeout(function(){ 
		if (!document.location || document.location.toString().indexOf(SERVER) != 0){
			return;
		}
		
		function bind(elem, evt, func){
			if (elem){
				return elem.addEventListener?elem.addEventListener(evt,func,false):elem.attachEvent("on"+evt,func);
			}
		}

		function storeHint() {
			var hint = new Array(); 
			var i = 0; 
			var a = document.getElementById("hint_" + i);
			var b = document.getElementById("hint_text_" + i);
			var storeClick = function(){sogouExplorer.extension.sendRequest({cmd: "click"});}
			while(a && b) {
				bind(a, "click", storeClick);
				hint.push({"text":b.innerHTML, "url":a.href});
				i++;
				a = document.getElementById("hint_" + i);
				b = document.getElementById("hint_text_" + i);
			}
			return hint;
		}
		
		if (document.getElementById("windowcloseit")){			
			document.getElementById("windowcloseit").onclick = function(){
				sogouExplorer.extension.sendRequest({cmd: "closeit"});
			}
			var flag = false;
			document.getElementById("bbconfig").onclick = function(){
				flag = true;
				sogouExplorer.extension.sendRequest({cmd: "config"});
				return false;
			}
			document.body.onclick = function(){
				if (flag) {
					flag = false;
				} else {
					sogouExplorer.extension.sendRequest({cmd: "closeconfig"});
				}
			};/*
			document.getElementById("bbhidden").onclick = function(){
				sogouExplorer.extension.sendRequest({cmd: "hide"});
				return false;
			}		*/
			var sogoutip = document.getElementById("sogoutip");
			var tip = {};
			tip.word = sogoutip.innerHTML;
			tip.config = sogoutip.title.split(",");
			var hint = storeHint();
			sogouExplorer.extension.sendRequest({cmd: "show", data: {hint:hint,tip:tip}});
		}else{
			if (document.getElementById("windowcloseitnow")){
				sogouExplorer.extension.sendRequest({cmd: "closeit", data: true});
			}
		}
	}, 1);
	
}



})(window.external.sogouExplorer(window,-1709349363));
}), 10);</script> <img src ="http://www.blogjava.net/bang/aggbug/372192.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bang/" target="_blank">邦</a> 2012-03-19 14:46 <a href="http://www.blogjava.net/bang/archive/2012/03/19/372192.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>