﻿<?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-void-随笔分类-MySql</title><link>http://www.blogjava.net/void241/category/33136.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 27 Jul 2016 23:28:22 GMT</lastBuildDate><pubDate>Wed, 27 Jul 2016 23:28:22 GMT</pubDate><ttl>60</ttl><item><title>Mysql 常用函数&amp;方法</title><link>http://www.blogjava.net/void241/archive/2016/07/22/431278.html</link><dc:creator>void</dc:creator><author>void</author><pubDate>Fri, 22 Jul 2016 03:50:00 GMT</pubDate><guid>http://www.blogjava.net/void241/archive/2016/07/22/431278.html</guid><wfw:comment>http://www.blogjava.net/void241/comments/431278.html</wfw:comment><comments>http://www.blogjava.net/void241/archive/2016/07/22/431278.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/void241/comments/commentRss/431278.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/void241/services/trackbacks/431278.html</trackback:ping><description><![CDATA[<div>FROM_UNIXTIME(UNIX_TIMESTAMP())， 系统当前时间+时间戳格式化<br /><pre style="font-family: 宋体; font-size: 9pt; background-color: #ffffff;"><span style="color:#008000;font-weight:bold;">INSERT INTO t_votes_summary (pkId,votes,systemVotes) <br />values(#{po.pkId},#{realTimeVotes},#{po.systemVotes})ON DUPLICATE KEY UPDATE votes=ifnull(votes,0)+#{realTimeVotes},systemVotes=ifnull(systemVotes,0)+#{systemVotes}， 如果主键重复，那么修改数值</span></pre></div><img src ="http://www.blogjava.net/void241/aggbug/431278.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/void241/" target="_blank">void</a> 2016-07-22 11:50 <a href="http://www.blogjava.net/void241/archive/2016/07/22/431278.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql 自增序列(转)</title><link>http://www.blogjava.net/void241/archive/2015/04/29/424762.html</link><dc:creator>void</dc:creator><author>void</author><pubDate>Wed, 29 Apr 2015 09:33:00 GMT</pubDate><guid>http://www.blogjava.net/void241/archive/2015/04/29/424762.html</guid><wfw:comment>http://www.blogjava.net/void241/comments/424762.html</wfw:comment><comments>http://www.blogjava.net/void241/archive/2015/04/29/424762.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/void241/comments/commentRss/424762.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/void241/services/trackbacks/424762.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1:原理是在建立一个触发器TRIGGER tri_NewBH  在table插入时执行序列计算 mysql&gt; CREATE TABLE tb(BH CHAR(16),content VARCHAR(20),`date` DATETIME,val INT); Query OK, 0 rows affected (0.05 sec)  mysql&gt; mysql&gt; mysql&gt; ...&nbsp;&nbsp;<a href='http://www.blogjava.net/void241/archive/2015/04/29/424762.html'>阅读全文</a><img src ="http://www.blogjava.net/void241/aggbug/424762.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/void241/" target="_blank">void</a> 2015-04-29 17:33 <a href="http://www.blogjava.net/void241/archive/2015/04/29/424762.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设置mysql允许外部IP连接的解决方法</title><link>http://www.blogjava.net/void241/archive/2012/06/09/380397.html</link><dc:creator>void</dc:creator><author>void</author><pubDate>Sat, 09 Jun 2012 02:07:00 GMT</pubDate><guid>http://www.blogjava.net/void241/archive/2012/06/09/380397.html</guid><wfw:comment>http://www.blogjava.net/void241/comments/380397.html</wfw:comment><comments>http://www.blogjava.net/void241/archive/2012/06/09/380397.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/void241/comments/commentRss/380397.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/void241/services/trackbacks/380397.html</trackback:ping><description><![CDATA[<div>mysql默认情况下，只允许localhost连接，如果需要外部IP连接到mysql，需要向mysql数据库里的&#8220;user&#8221;表里添加相关授权。 <div>&nbsp;<wbr>&nbsp;<wbr> 例如：让newuser用户使用newpwd密码从IP：192.168.1.3主机链接到mysql服务器&nbsp;<wbr>&nbsp;<wbr><br /> &nbsp;<wbr>&nbsp;<wbr><br /> &nbsp;<wbr>&nbsp;<wbr> 具体步骤：<br /> &nbsp;<wbr>&nbsp;<wbr> mysql&gt;GRANT ALL PRIVILEGES ON *.* TO <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#37;&#50;&#55;&#110;&#101;&#119;&#117;&#115;&#101;&#114;&#37;&#50;&#55;&#64;&#37;&#50;&#55;&#49;&#57;&#50;&#46;&#49;&#54;&#56;&#46;&#49;&#46;&#51;&#37;&#50;&#55;">'newuser'@'192.168.1.3'</a> IDENTIFIED BY 'newpwd' WITH GRANT OPTION;<br /> &nbsp;<wbr>&nbsp;<wbr> mysql&gt;flush privileges;&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><br /> &nbsp;<wbr>&nbsp;<wbr><br /> &nbsp;<wbr>&nbsp;<wbr> grant语法：<br /> &nbsp;<wbr>&nbsp;<wbr> grant 权限名（所有的权限用all） on&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 库名（*全部）.表名（*全部） to&nbsp;<wbr> '要授权的用户名<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#37;&#50;&#55;&#64;&#37;&#50;&#55;&#37;&#37;&#50;&#55;&#37;&#50;&#56;&#37;">'@'%'(%</a>表示所有的IP，可以只些一个IP） identified by "密码"；</div> <div>身份检查使用user表(Host, User和Password)3个范围列执行。服务器只有在user表记录的Host和User列匹配客户端主机名和用户名并且提供了正确的密码时才接受连接。</div> <div>在user表Host值的指定方法：</div> <div>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> * Host值可以是主机名或IP号，或'localhost'指出本地主机。<br /> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> * 你可以在Host列值使用通配符字符&#8220;%&#8221;和&#8220;_&#8221;。<br /> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> * Host值'%'匹配任何主机名，空Host值等价于'%'。它们的含义与LIKE操作符的模式匹配操作相同。例如，'%'的Host值与所有主机名匹配，而'%.mysql.com'匹配mysql.com域</div> <div>的所有主机。</div></div><img src ="http://www.blogjava.net/void241/aggbug/380397.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/void241/" target="_blank">void</a> 2012-06-09 10:07 <a href="http://www.blogjava.net/void241/archive/2012/06/09/380397.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux本机自动备份MYSQL方法</title><link>http://www.blogjava.net/void241/archive/2009/06/23/283746.html</link><dc:creator>void</dc:creator><author>void</author><pubDate>Tue, 23 Jun 2009 07:11:00 GMT</pubDate><guid>http://www.blogjava.net/void241/archive/2009/06/23/283746.html</guid><wfw:comment>http://www.blogjava.net/void241/comments/283746.html</wfw:comment><comments>http://www.blogjava.net/void241/archive/2009/06/23/283746.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/void241/comments/commentRss/283746.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/void241/services/trackbacks/283746.html</trackback:ping><description><![CDATA[<p>MYSQL定期备份是一项重要的工作，但人工操作太繁琐，也难避免有所疏漏，使用下面的方法即可让系统定期备份数据。</p>
<p>1、创建备份文件夹</p>
<p>#cd /www<br />
#makedir backup</p>
<p>2、编写运行脚本</p>
<p>#vi autobackup</p>
<p>写入以下内容：</p>
<p>filename=`date +%Y%m%d`<br />
mysql_bin_dir/mysqldump &#8211;opt dataname -u user -ppassword | gzip &gt; /www/mysqlbackup/name$filename.gz</p>
<p>保存退出 </p>
<p>说明：</p>
<p>(1)mysql_bin_dir：mysql的bin路径；</p>
<p>(2)dataname：数据库名；</p>
<p>(3)user：数据库用户名；</p>
<p>(4)password：用户密码；</p>
<p>(5)name：自定义备份文件前缀标识。</p>
<p>如上例，将自动备份mysql数据库，并以gzip压缩方式存储，文件名为name20080101.gz的形式。</p>
<p>3、为脚本添加执行权限</p>
<p>#chmod +x autobackup</p>
<p>4、让crontab来完成定期执行的任务</p>
<p>这一步中，Redhat的方法会不一样，后面专门给出。</p>
<p>编辑crontab：</p>
<p>#vi /etc/crontab</p>
<p>在最后一行中加入：</p>
<p>01 5 * * * root /www/autobackup</p>
<p>每天5点运行脚本，也可以修改5为其他指定时间。</p>
<p>Redhat方法：</p>
<p>Redhat的crontab采用按时间调用4个目录（/etc/cron.hourly：每小时；/etc/cron.daily：每天；/etc/cron.weekly：每周；/etc/cron.monthly：每月）中脚本出来运行的方式。</p>
<p>Redhat中只需要将刚才编辑的脚本复制到相应的目录即可。</p>
<p>5、重启crontab</p>
<p>#/etc/rc.d/init.d/crond restart</p>
<p>完成</p>
<p>其实原理很简单，自己制作一个脚本，让Linux系统自动运行。我们还可以再扩展一下，编辑一个自动备份网站文件的脚本，让Linux来完成，每天自动备份整个网站，等等&#8230;&#8230;</p>
<p><br />
本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/seosem/archive/2008/03/07/2156074.aspx</p>
<img src ="http://www.blogjava.net/void241/aggbug/283746.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/void241/" target="_blank">void</a> 2009-06-23 15:11 <a href="http://www.blogjava.net/void241/archive/2009/06/23/283746.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL分区（Partition）功能试验</title><link>http://www.blogjava.net/void241/archive/2009/03/26/262063.html</link><dc:creator>void</dc:creator><author>void</author><pubDate>Thu, 26 Mar 2009 04:22:00 GMT</pubDate><guid>http://www.blogjava.net/void241/archive/2009/03/26/262063.html</guid><wfw:comment>http://www.blogjava.net/void241/comments/262063.html</wfw:comment><comments>http://www.blogjava.net/void241/archive/2009/03/26/262063.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/void241/comments/commentRss/262063.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/void241/services/trackbacks/262063.html</trackback:ping><description><![CDATA[<p>MySQL分区（Partition）功能试验<br />
2008-07-06 20:02目录<br />
[概述]<br />
[分区表和未分区表试验过程]<br />
[分区命令详解]</p>
<p>[概述]</p>
<p>自5.1开始对分区(Partition)有支持，6.0应比较稳定</p>
<p>= 水平分区（根据列属性按行分）=<br />
举个简单例子：一个包含十年发票记录的表可以被分区为十个不同的分区，每个分区包含的是其中一年的记录。</p>
<p>=== 水平分区的几种模式：===<br />
* Range（范围） &#8211; 这种模式允许DBA将数据划分不同范围。例如DBA可以将一个表通过年份划分成三个分区，80年代（1980's）的数据，90年代（1990's）的数据以及任何在2000年（包括2000年）后的数据。</p>
<p>* Hash（哈希） &#8211; 这中模式允许DBA通过对表的一个或多个列的Hash Key进行计算，最后通过这个Hash码不同数值对应的数据区域进行分区，。例如DBA可以建立一个对表主键进行分区的表。</p>
<p>* Key（键值） &#8211; 上面Hash模式的一种延伸，这里的Hash Key是MySQL系统产生的。</p>
<p>* List（预定义列表） &#8211; 这种模式允许系统通过DBA定义的列表的值所对应的行数据进行分割。例如：DBA建立了一个横跨三个分区的表，分别根据2004年2005年和2006年值所对应的数据。</p>
<p>* Composite（复合模式） - 很神秘吧，哈哈，其实是以上模式的组合使用而已，就不解释了。举例：在初始化已经进行了Range范围分区的表上，我们可以对其中一个分区再进行hash哈希分区。</p>
<p>= 垂直分区（按列分）=<br />
举个简单例子：一个包含了大text和BLOB列的表，这些text和BLOB列又不经常被访问，这时候就要把这些不经常使用的text和BLOB了划分到另一个分区，在保证它们数据相关性的同时还能提高访问速度。</p>
<p><br />
[分区表和未分区表试验过程]</p>
<p>*创建分区表,按日期的年份拆分<br />
mysql&gt; CREATE TABLE part_tab ( c1 int default NULL, c2 varchar(30) default NULL, c3 date default NULL) engine=myisam <br />
PARTITION BY RANGE (year(c3)) (PARTITION p0 VALUES LESS THAN (1995),<br />
PARTITION p1 VALUES LESS THAN (1996) , PARTITION p2 VALUES LESS THAN (1997) ,<br />
PARTITION p3 VALUES LESS THAN (1998) , PARTITION p4 VALUES LESS THAN (1999) ,<br />
PARTITION p5 VALUES LESS THAN (2000) , PARTITION p6 VALUES LESS THAN (2001) ,<br />
PARTITION p7 VALUES LESS THAN (2002) , PARTITION p8 VALUES LESS THAN (2003) ,<br />
PARTITION p9 VALUES LESS THAN (2004) , PARTITION p10 VALUES LESS THAN (2010),<br />
PARTITION p11 VALUES LESS THAN MAXVALUE ); <br />
注意最后一行，考虑到可能的最大值</p>
<p>*创建未分区表<br />
mysql&gt; create table no_part_tab (c1 int(11) default NULL,c2 varchar(30) default NULL,c3 date default NULL) engine=myisam;</p>
<p>*通过存储过程灌入800万条测试数据</p>
<p>mysql&gt; set sql_mode=''; /* 如果创建存储过程失败，则先需设置此变量, bug? */</p>
<p>mysql&gt; delimiter //&nbsp;&nbsp; /* 设定语句终结符为 //，因存储过程语句用;结束 */<br />
mysql&gt; CREATE PROCEDURE load_part_tab()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br />
&nbsp;&nbsp;&nbsp; declare v int default 0;<br />
&nbsp;&nbsp;&nbsp; while v &lt; 8000000<br />
&nbsp;&nbsp;&nbsp; do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert into part_tab<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; values (v,'testing partitions',adddate('1995-01-01',(rand(v)*36520) mod 3652));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set v = v + 1;<br />
&nbsp;&nbsp;&nbsp; end while;<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; //<br />
mysql&gt; delimiter ;<br />
mysql&gt; call load_part_tab();<br />
Query OK, 1 row affected (8 min 17.75 sec)<br />
mysql&gt; insert into no_part_tab select * from part_tab;<br />
Query OK, 8000000 rows affected (51.59 sec)<br />
Records: 8000000 Duplicates: 0 Warnings: 0</p>
<p>* 测试SQL性能<br />
mysql&gt; select count(*) from part_tab where c3 &gt; date '1995-01-01' and c3 &lt; date '1995-12-31';&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
+----------+<br />
| count(*) |<br />
+----------+<br />
|&nbsp;&nbsp; 795181 |<br />
+----------+<br />
1 row in set (0.55 sec)<br />
mysql&gt; select count(*) from no_part_tab where c3 &gt; date '1995-01-01' and c3 &lt; date '1995-12-31'; <br />
+----------+<br />
| count(*) |<br />
+----------+<br />
|&nbsp;&nbsp; 795181 |<br />
+----------+<br />
1 row in set (4.69 sec)<br />
结果表明分区表比未分区表的执行时间少90%。</p>
<p>* 通过explain语句来分析执行情况<br />
mysql &gt; explain select count(*) from no_part_tab where c3 &gt; date '1995-01-01' and c3 &lt; date '1995-12-31'\G<br />
/* 结尾的\G使得mysql的输出改为列模式 */&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
*************************** 1. row ***************************<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id: 1<br />
select_type: SIMPLE<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table: no_part_tab<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type: ALL<br />
possible_keys: NULL<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key: NULL<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key_len: NULL<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ref: NULL<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rows: 8000000<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Extra: Using where<br />
1 row in set (0.00 sec)</p>
<p>mysql&gt; explain select count(*) from part_tab where c3 &gt; date '1995-01-01' and c3 &lt; date '1995-12-31'\G <br />
*************************** 1. row ***************************<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id: 1<br />
select_type: SIMPLE<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table: part_tab<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type: ALL<br />
possible_keys: NULL<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key: NULL<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key_len: NULL<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ref: NULL<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rows: 798458<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Extra: Using where<br />
1 row in set (0.00 sec)<br />
explain语句显示了SQL查询要处理的记录数目</p>
<p>* 试验创建索引后情况<br />
mysql&gt; create index idx_of_c3 on no_part_tab (c3);<br />
Query OK, 8000000 rows affected (1 min 18.08 sec)<br />
Records: 8000000 Duplicates: 0 Warnings: 0</p>
<p>mysql&gt; create index idx_of_c3 on part_tab (c3);<br />
Query OK, 8000000 rows affected (1 min 19.19 sec)<br />
Records: 8000000 Duplicates: 0 Warnings: 0<br />
创建索引后的数据库文件大小列表：<br />
2008-05-24 09:23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,608 no_part_tab.frm<br />
2008-05-24 09:24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 255,999,996 no_part_tab.MYD<br />
2008-05-24 09:24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 81,611,776 no_part_tab.MYI<br />
2008-05-24 09:25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 part_tab#P#p0.MYD<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1,024 part_tab#P#p0.MYI<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25,550,656 part_tab#P#p1.MYD<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,148,992 part_tab#P#p1.MYI<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25,620,192 part_tab#P#p10.MYD<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,170,496 part_tab#P#p10.MYI<br />
2008-05-24 09:25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 part_tab#P#p11.MYD<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1,024 part_tab#P#p11.MYI<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25,656,512 part_tab#P#p2.MYD<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,181,760 part_tab#P#p2.MYI<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25,586,880 part_tab#P#p3.MYD<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,160,256 part_tab#P#p3.MYI<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25,585,696 part_tab#P#p4.MYD<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,159,232 part_tab#P#p4.MYI<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25,585,216 part_tab#P#p5.MYD<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,159,232 part_tab#P#p5.MYI<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25,655,740 part_tab#P#p6.MYD<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,181,760 part_tab#P#p6.MYI<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25,586,528 part_tab#P#p7.MYD<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,160,256 part_tab#P#p7.MYI<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25,586,752 part_tab#P#p8.MYD<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,160,256 part_tab#P#p8.MYI<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25,585,824 part_tab#P#p9.MYD<br />
2008-05-24 09:26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,159,232 part_tab#P#p9.MYI<br />
2008-05-24 09:25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,608 part_tab.frm<br />
2008-05-24 09:25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 68 part_tab.par</p>
<p>* 再次测试SQL性能<br />
mysql&gt; select count(*) from no_part_tab where c3 &gt; date '1995-01-01' and c3 &lt; date '1995-12-31';&nbsp;&nbsp;&nbsp; +----------+<br />
| count(*) |<br />
+----------+<br />
|&nbsp;&nbsp; 795181 |<br />
+----------+<br />
1 row in set (2.42 sec)&nbsp;&nbsp; /* 为原来4.69 sec 的51%*/&nbsp;&nbsp; <br />
重启mysql ( net stop mysql, net start mysql)后，查询时间降为0.89 sec,几乎与分区表相同。</p>
<p>mysql&gt; select count(*) from part_tab where c3 &gt; date '1995-01-01' and c3 &lt; date '1995-12-31'; <br />
+----------+<br />
| count(*) |<br />
+----------+<br />
|&nbsp;&nbsp; 795181 |<br />
+----------+<br />
1 row in set (0.86 sec)</p>
<p>* 更进一步的试验<br />
** 增加日期范围<br />
mysql&gt; select count(*) from no_part_tab where c3 &gt; date '1995-01-01' and c3 &lt; date '1997-12-31';<br />
+----------+<br />
| count(*) |<br />
+----------+<br />
| 2396524 |<br />
+----------+<br />
1 row in set (5.42 sec)</p>
<p>mysql&gt; select count(*) from part_tab where c3 &gt; date '1995-01-01' and c3 &lt; date '1997-12-31';<br />
+----------+<br />
| count(*) |<br />
+----------+<br />
| 2396524 |<br />
+----------+<br />
1 row in set (2.63 sec)<br />
** 增加未索引字段查询<br />
mysql&gt; select count(*) from part_tab where c3 &gt; date '1995-01-01' and c3 &lt; date<br />
'1996-12-31' and c2='hello';<br />
+----------+<br />
| count(*) |<br />
+----------+<br />
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 |<br />
+----------+<br />
1 row in set (0.75 sec)</p>
<p>mysql&gt; select count(*) from no_part_tab where c3 &gt; date '1995-01-01' and c3 &lt; da<br />
te '1996-12-31' and c2='hello';<br />
+----------+<br />
| count(*) |<br />
+----------+<br />
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 |<br />
+----------+<br />
1 row in set (11.52 sec)</p>
<p><br />
= 初步结论 =<br />
* 分区和未分区占用文件空间大致相同 （数据和索引文件）<br />
* 如果查询语句中有未建立索引字段，分区时间远远优于未分区时间<br />
* 如果查询语句中字段建立了索引，分区和未分区的差别缩小，分区略优于未分区。</p>
<p><br />
= 最终结论 =<br />
* 对于大数据量，建议使用分区功能。<br />
* 去除不必要的字段<br />
* 根据手册， 增加myisam_max_sort_file_size 会增加分区性能</p>
<p>[分区命令详解]</p>
<p>= 分区例子 = <br />
* RANGE 类型</p>
<p>CREATE TABLE users (<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name VARCHAR(30) NOT NULL DEFAULT '',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; email VARCHAR(30) NOT NULL DEFAULT ''<br />
)<br />
PARTITION BY RANGE (uid) (<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p0 VALUES LESS THAN (3000000)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data0/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data1/idx',</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p1 VALUES LESS THAN (6000000)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data2/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data3/idx',</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p2 VALUES LESS THAN (9000000)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data4/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data5/idx',</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p3 VALUES LESS THAN MAXVALUE&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data6/data' <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data7/idx'<br />
);</p>
<p>在这里，将用户表分成4个分区，以每300万条记录为界限，每个分区都有自己独立的数据、索引文件的存放目录，与此同时，这些目录所在的物理磁盘分区可能也都是完全独立的，可以提高磁盘IO吞吐量。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
* LIST 类型</p>
<p>CREATE TABLE category (<br />
&nbsp;&nbsp;&nbsp;&nbsp; cid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,<br />
&nbsp;&nbsp;&nbsp;&nbsp; name VARCHAR(30) NOT NULL DEFAULT ''<br />
)<br />
PARTITION BY LIST (cid) (<br />
&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p0 VALUES IN (0,4,8,12)<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data0/data' <br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data1/idx',<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p1 VALUES IN (1,5,9,13)<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data2/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data3/idx',<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p2 VALUES IN (2,6,10,14)<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data4/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data5/idx',<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p3 VALUES IN (3,7,11,15)<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data6/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data7/idx'<br />
);&nbsp;&nbsp;</p>
<p>分成4个区，数据文件和索引文件单独存放。</p>
<p>* HASH 类型&nbsp;&nbsp;&nbsp;&nbsp; <br />
CREATE TABLE users (<br />
&nbsp;&nbsp;&nbsp;&nbsp; uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,<br />
&nbsp;&nbsp;&nbsp;&nbsp; name VARCHAR(30) NOT NULL DEFAULT '',<br />
&nbsp;&nbsp;&nbsp;&nbsp; email VARCHAR(30) NOT NULL DEFAULT ''<br />
)<br />
PARTITION BY HASH (uid) PARTITIONS 4 (<br />
&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p0<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data0/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data1/idx',</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p1<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data2/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data3/idx',</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p2<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data4/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data5/idx',</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p3<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data6/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data7/idx'<br />
);<br />
分成4个区，数据文件和索引文件单独存放。</p>
<p>例子：<br />
CREATE TABLE ti2 (id INT, amount DECIMAL(7,2), tr_date DATE)<br />
&nbsp;&nbsp;&nbsp; ENGINE=myisam<br />
&nbsp;&nbsp;&nbsp; PARTITION BY HASH( MONTH(tr_date) )<br />
&nbsp;&nbsp;&nbsp; PARTITIONS 6;</p>
<p>CREATE PROCEDURE load_ti2()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br />
&nbsp;&nbsp;&nbsp; declare v int default 0;<br />
&nbsp;&nbsp;&nbsp; while v &lt; 80000<br />
&nbsp;&nbsp;&nbsp; do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert into ti2<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; values (v,'3.14',adddate('1995-01-01',(rand(v)*3652) mod 365));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set v = v + 1;<br />
&nbsp;&nbsp;&nbsp; end while;<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; //</p>
<p>&nbsp;</p>
<p>* KEY 类型<br />
CREATE TABLE users (<br />
&nbsp;&nbsp;&nbsp;&nbsp; uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,<br />
&nbsp;&nbsp;&nbsp;&nbsp; name VARCHAR(30) NOT NULL DEFAULT '',<br />
&nbsp;&nbsp;&nbsp;&nbsp; email VARCHAR(30) NOT NULL DEFAULT ''<br />
)<br />
PARTITION BY KEY (uid) PARTITIONS 4 (<br />
&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p0<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data0/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data1/idx',<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p1<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data2/data' <br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data3/idx',<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p2 <br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data4/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data5/idx',<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p3 <br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data6/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data7/idx'<br />
);&nbsp;&nbsp; <br />
分成4个区，数据文件和索引文件单独存放。</p>
<p>* 子分区<br />
子分区是针对 RANGE/LIST 类型的分区表中每个分区的再次分割。再次分割可以是 HASH/KEY 等类型。例如：<br />
CREATE TABLE users (<br />
&nbsp;&nbsp;&nbsp;&nbsp; uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,<br />
&nbsp;&nbsp;&nbsp;&nbsp; name VARCHAR(30) NOT NULL DEFAULT '',<br />
&nbsp;&nbsp;&nbsp;&nbsp; email VARCHAR(30) NOT NULL DEFAULT ''<br />
)<br />
PARTITION BY RANGE (uid) SUBPARTITION BY HASH (uid % 4) SUBPARTITIONS 2(<br />
&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p0 VALUES LESS THAN (3000000)<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data0/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data1/idx',</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p1 VALUES LESS THAN (6000000)<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data2/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data3/idx'<br />
);</p>
<p>对 RANGE 分区再次进行子分区划分，子分区采用 HASH 类型。</p>
<p>或者</p>
<p>CREATE TABLE users (<br />
&nbsp;&nbsp;&nbsp;&nbsp; uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,<br />
&nbsp;&nbsp;&nbsp;&nbsp; name VARCHAR(30) NOT NULL DEFAULT '',<br />
&nbsp;&nbsp;&nbsp;&nbsp; email VARCHAR(30) NOT NULL DEFAULT ''<br />
)<br />
PARTITION BY RANGE (uid) SUBPARTITION BY KEY(uid) SUBPARTITIONS 2(<br />
&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p0 VALUES LESS THAN (3000000)<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data0/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data1/idx',</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; PARTITION p1 VALUES LESS THAN (6000000)<br />
&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data2/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data3/idx'<br />
);</p>
<p>对 RANGE 分区再次进行子分区划分，子分区采用 KEY 类型。</p>
<p>= 分区管理 =</p>
<p>&nbsp;&nbsp;&nbsp; * 删除分区</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ALERT TABLE users DROP PARTITION p0;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除分区 p0。<br />
&nbsp;&nbsp;&nbsp; * 重建分区<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o RANGE 分区重建</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ALTER TABLE users REORGANIZE PARTITION p0,p1 INTO (PARTITION p0 VALUES LESS THAN (6000000));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将原来的 p0,p1 分区合并起来，放到新的 p0 分区中。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o LIST 分区重建</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ALTER TABLE users REORGANIZE PARTITION p0,p1 INTO (PARTITION p0 VALUES IN(0,1,4,5,8,9,12,13));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将原来的 p0,p1 分区合并起来，放到新的 p0 分区中。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o HASH/KEY 分区重建</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ALTER TABLE users REORGANIZE PARTITION COALESCE PARTITION 2;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用 REORGANIZE 方式重建分区的数量变成2，在这里数量只能减少不能增加。想要增加可以用 ADD PARTITION 方法。<br />
&nbsp;&nbsp;&nbsp; * 新增分区<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o 新增 RANGE 分区</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ALTER TABLE category ADD PARTITION (PARTITION p4 VALUES IN (16,17,18,19)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DATA DIRECTORY = '/data8/data'<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INDEX DIRECTORY = '/data9/idx');</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 新增一个RANGE分区。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o 新增 HASH/KEY 分区</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ALTER TABLE users ADD PARTITION PARTITIONS 8;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将分区总数扩展到8个。</p>
<p>[ 给已有的表加上分区 ]</p>
<p>alter table results partition by RANGE (month(ttime)) <br />
(PARTITION p0 VALUES LESS THAN (1),<br />
PARTITION p1 VALUES LESS THAN (2) , PARTITION p2 VALUES LESS THAN (3) ,<br />
PARTITION p3 VALUES LESS THAN (4) , PARTITION p4 VALUES LESS THAN (5) ,<br />
PARTITION p5 VALUES LESS THAN (6) , PARTITION p6 VALUES LESS THAN (7) ,<br />
PARTITION p7 VALUES LESS THAN (8) , PARTITION p8 VALUES LESS THAN (9) ,<br />
PARTITION p9 VALUES LESS THAN (10) , PARTITION p10 VALUES LESS THAN (11),<br />
PARTITION p11 VALUES LESS THAN (12),<br />
PARTITION P12 VALUES LESS THAN (13) );</p>
<p>默认分区限制分区字段必须是主键（PRIMARY KEY)的一部分，为了去除此<br />
限制：<br />
[方法1] 使用ID<br />
mysql&gt; ALTER TABLE np_pk<br />
&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; PARTITION BY HASH( TO_DAYS(added) )<br />
&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; PARTITIONS 4;<br />
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function</p>
<p>However, this statement using the id column for the partitioning column is valid, as shown here:</p>
<p>mysql&gt; ALTER TABLE np_pk<br />
&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; PARTITION BY HASH(id)<br />
&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; PARTITIONS 4;<br />
Query OK, 0 rows affected (0.11 sec)<br />
Records: 0 Duplicates: 0 Warnings: 0</p>
<p>[方法2] 将原有PK去掉生成新PK<br />
mysql&gt; alter table results drop PRIMARY KEY;<br />
Query OK, 5374850 rows affected (7 min 4.05 sec)<br />
Records: 5374850 Duplicates: 0 Warnings: 0</p>
<p>mysql&gt; alter table results add PRIMARY KEY(id, ttime);<br />
Query OK, 5374850 rows affected (6 min 14.86 sec)<br />
Records: 5374850 Duplicates: 0 Warnings: 0</p>
<img src ="http://www.blogjava.net/void241/aggbug/262063.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/void241/" target="_blank">void</a> 2009-03-26 12:22 <a href="http://www.blogjava.net/void241/archive/2009/03/26/262063.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySql帐户的创建与删除、口令更改</title><link>http://www.blogjava.net/void241/archive/2008/08/20/223165.html</link><dc:creator>void</dc:creator><author>void</author><pubDate>Wed, 20 Aug 2008 02:08:00 GMT</pubDate><guid>http://www.blogjava.net/void241/archive/2008/08/20/223165.html</guid><wfw:comment>http://www.blogjava.net/void241/comments/223165.html</wfw:comment><comments>http://www.blogjava.net/void241/archive/2008/08/20/223165.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/void241/comments/commentRss/223165.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/void241/services/trackbacks/223165.html</trackback:ping><description><![CDATA[. 创建用户账户可以用三种方式创建<span>MySQL</span>账户：
<p><span>1 </span>使用<span>GRANT</span>语句</p>
<p><span>2 </span>直接操作<span>MySQL</span>授权表</p>
<p>3 使用CREATE USER语句<br />
</p>
<p>最好的方法是使用<span>GRANT</span>语句，因为这样更精确，错误少。</p>
<p>创建账户的其它方法是使用<span>MySQL</span>账户管理功能的第三方程序。<span>phpMyAdmin</span>即是一个程序。</p>
<p>下面的示例说明如何使用<strong><span>MySQL</span></strong>客户端程序来设置新用户。为了更改，你必须以<span>MySQL </span><span>root</span>用户连接<span>MySQL</span>服务器，并且<span>root</span>账户必须有<span>mysql</span>数据库的<span>INSERT</span>权限和<span>RELOAD</span>管理权限。</p>
<p>首先，使用<strong><span>MySQL</span></strong>程序以<span>MySQL </span><span>root</span>用户来连接服务器：</p>
<pre><span>shell&gt; </span><span>MySQL<strong> --user=root </strong>MySQL</span></pre>
<p>如果你为<span>root</span>账户指定了密码，还需要为该<strong><span>MySQL</span></strong>命令和本节中的其它命令提供<span>--password</span>或<span>-p</span>选项。</p>
<p><span>以<span>root</span></span>连接到服务器上后，可以添加新账户。下面的语句使用<span>GRANT</span>来设置四个新账户：</p>
<pre><span>mysql&gt; </span><span><strong><span>GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp;      -&gt;&nbsp;&nbsp;&nbsp;&nbsp;      </span><span><strong><span>IDENTIFIED BY 'some_pass' WITH GRANT OPTION;</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp;      -&gt;&nbsp;&nbsp;&nbsp;&nbsp;      </span><span><strong><span>IDENTIFIED BY 'some_pass' WITH GRANT OPTION;</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>GRANT RELOAD,PROCESS ON *.* TO 'admin'@'localhost';</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>GRANT USAGE ON *.* TO 'dummy'@'localhost';</span></strong></span></pre>
<br />
<p>除了<span>GRANT</span>，你可以直接用<span>INSERT</span>语句创建相同的账户，然后使用<span>FLUSH PRIVILEGES</span>告诉服务器重载授权表：</p>
<pre><span>shell&gt; </span><span><strong><span>mysql --user=root mysql</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO user</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp;      -&gt;&nbsp;&nbsp;&nbsp;&nbsp;      </span><span><strong><span>VALUES('localhost','monty',PASSWORD('some_pass'),</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp;      -&gt;&nbsp;&nbsp;&nbsp;&nbsp;      </span><span><strong><span>'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO user</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp;      -&gt;&nbsp;&nbsp;&nbsp;&nbsp;      </span><span><strong><span>VALUES('%','monty',PASSWORD('some_pass'),</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp;      -&gt;&nbsp;&nbsp;&nbsp;&nbsp;      </span><span><strong><span>'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO user SET Host='localhost',User='admin',</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp;      -&gt;&nbsp;&nbsp;&nbsp;&nbsp;      </span><span><strong><span>Reload_priv='Y', Process_priv='Y';</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO user (Host,User,Password)</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp;      -&gt;&nbsp;&nbsp;&nbsp;&nbsp;      </span><span><strong><span>VALUES('localhost','dummy','');</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>FLUSH PRIVILEGES;</span></strong></span></pre>
<p>当你用<span>INSERT</span>创建账户时使用<span>FLUSH PRIVILEGES</span>的原因是告诉服务器重读授权表。否则，只有重启服务器后更改方会被注意到。使用 <span>GRANT</span>，则不需要使用<span>FLUSH PRIVILEGES</span>。</p>
<p>用<span>INSERT</span>使用<span>PASSWORD()</span>函数是为了加密密码。<span>GRANT</span>语句为你加密密码，因此不需要<span>PASSWORD()</span>。</p>
<p><span>'Y'</span>值启用账户权限。对于<span>admin</span>账户，还可以使用更加可读的<span>INSERT</span>扩充的语法（使用<span>SET</span>）。</p>
<p>在为<span>dummy</span>账户的<span>INSERT</span>语句中，只有<span>user</span>表中的<span>Host</span>、<span>User</span>和<span>Password</span>列记录为指定的值。没有一个权限列为显式设置，因此<span>MySQL</span>将它们均指定为 默认值<span>'N'</span>。这样等同于<span>GRANT USAGE</span>的操作。</p>
<p>请注意要设置超级用户账户，只需要创建一个权限列设置为<span>'Y'</span>的<span>user</span>表条目。<span>user</span>表权限为全局权限，因此其它 授权表不再需要条目。</p>
第三种方法，CREATE USER语句。<br />
<pre><span>shell&gt; </span><span><strong><span>mysql --user=root<br />
</span></strong></span><span>mysql&gt; create user 'jian'@'localhost' identified by 'my123'；#账户密码设置和grant语句类似<br />
</span></pre>
<h3>2.删除用户账户</h3>
<h3>要想移除账户，应使用<span>DROP USER</span>语句.</h3>
<div>
<pre><span>mysql&gt;</span>drop user <a href="mailto:'jian'@'localhost'">'jian'@'localhost'</a>;</pre>
</div>
<h3>3.更改账户口令</h3>
<p>设置MySQL用户帐号密码的方法有三种：</p>
<ul type="disc">
    <li>
    <p>使用mysqladmin程序：</p>
    <pre>% mysqladmin -h localhost -u root password "password"   #设置在本地以root身分登录的密码<br />
    % mysqladmin -h remote -u root password "password"      #设置远程主机以root身分登录的密码<br />
    </pre>
    <p>在初始设置时，这两条语句都要运行，以确保数据库本地访问和网络访问的安全。</p>
    <li>
    <p>通过set password这条SQL语句设置：</p>
    <pre>mysql&gt; set password for 'root'@'localhost' = password('password');<br />
    mysql&gt; set password for 'root'@'remote' = password('password');<br />
    </pre>
    <li>
    <p>直接修改user权限表：</p>
    <pre>mysql&gt; use mysql;<br />
    mysql&gt; update user set password=password('password') where user='root';<br />
    mysql&gt; flush privileges;                            #重载权限表，使修改马上生效<br />
    </pre>
    </li>
</ul>
<img src ="http://www.blogjava.net/void241/aggbug/223165.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/void241/" target="_blank">void</a> 2008-08-20 10:08 <a href="http://www.blogjava.net/void241/archive/2008/08/20/223165.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux下mysql远程登陆</title><link>http://www.blogjava.net/void241/archive/2008/07/28/217920.html</link><dc:creator>void</dc:creator><author>void</author><pubDate>Sun, 27 Jul 2008 18:22:00 GMT</pubDate><guid>http://www.blogjava.net/void241/archive/2008/07/28/217920.html</guid><wfw:comment>http://www.blogjava.net/void241/comments/217920.html</wfw:comment><comments>http://www.blogjava.net/void241/archive/2008/07/28/217920.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/void241/comments/commentRss/217920.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/void241/services/trackbacks/217920.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt"><span style="font-size: 10pt"><span style="font-size: 12pt"><span style="font-family: 宋体"><font size="3">解决方法：<br />
<br />
</font><font size="3">1。 改表法。可能是你的帐号不允许从远程登陆，只能在localhost。这个时候只要在localhost的那台电脑，登入mysql后，更改 "mysql" 数据库里的 "user" 表里的 "host" 项，从"localhost"改称"%"<br />
mysql -u root -p123<br />
mysql&gt;use mysql;<br />
mysql&gt;update user set host = '%' where user = 'root';<br />
mysql&gt;select host, user from user;<br />
<br />
2. 授权法。例如，你想kevin使用mypassword从任何主机连接到mysql服务器的话。<br />
GRANT ALL PRIVILEGES ON *.* TO 'kevin'@'%' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;<br />
如果你想允许用户kevin从ip为192.168.101.234的主机连接到mysql服务器，并使用mypassword作为密码<br />
GRANT ALL PRIVILEGES ON *.* TO 'kevin'@'192.168.101.234' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;<br />
<br />
3.如果按照上面这样做还不行(一般好像在windows下那样就可以了)那就修改下面这个配置文件吧(我是在linux环境下 大家可以找到自己mysql安装目录下的相应配置文件)<br />
vi&nbsp; /etc/mysql/my.cnf<br />
注释掉<br />
#bind-address&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 127.0.0.1</font></span></span></span></span>
<img src ="http://www.blogjava.net/void241/aggbug/217920.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/void241/" target="_blank">void</a> 2008-07-28 02:22 <a href="http://www.blogjava.net/void241/archive/2008/07/28/217920.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySql备份</title><link>http://www.blogjava.net/void241/archive/2008/07/19/216007.html</link><dc:creator>void</dc:creator><author>void</author><pubDate>Sat, 19 Jul 2008 04:21:00 GMT</pubDate><guid>http://www.blogjava.net/void241/archive/2008/07/19/216007.html</guid><wfw:comment>http://www.blogjava.net/void241/comments/216007.html</wfw:comment><comments>http://www.blogjava.net/void241/archive/2008/07/19/216007.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/void241/comments/commentRss/216007.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/void241/services/trackbacks/216007.html</trackback:ping><description><![CDATA[<strong><font style="background-color: #a0ffff">备份</font></strong>与恢复<br />
常规<strong style="color: black; background-color: #a0ffff">备份</strong>命令是mysqldump,这里以tm数据库为例，做简单介绍，详细资料参考<br />
<a style="color: #000000" href="http://info.mysql.cn/install/2006/0410/5521.html" target="_blank">http://info.<strong style="color: black; background-color: #ffff66">mysql</strong>.cn/install/2006/0410/5521.html</a><br />
<strong style="color: black; background-color: #a0ffff">备份</strong>：<br />
#mysqldump -u root -p tm &gt; tm_20060101.sql&nbsp;&nbsp;<br />
按提示输入密码，这就把tm数据库所有的表结构和数据<strong style="color: black; background-color: #a0ffff">备份</strong>到tm_20060101.sql了，因为要总进行<strong style="color: black; background-color: #a0ffff">备份</strong>工作，如果数据量大会占用很大空间，<br />
这是可以利用gzip压缩数据，命令如下：<br />
#mysqldump -u root -p tm | gzip &gt; tm_20060101.sql.gz<br />
还可以<strong style="color: black; background-color: #a0ffff">备份</strong>到远程机器，用-h制定，如<br />
#mysqldump -u root -p tm &gt; tm_20060101.sql -h xxx.xxx.xxx.xxx<br />
可以直接<strong style="color: black; background-color: #a0ffff">备份</strong>到IP地址为xxx.xxx.xxx.xxx的远程计算机。<br />
系统崩溃，重建系统，或恢复数据库时，可以这样恢复数据：<br />
#<strong style="color: black; background-color: #ffff66">mysql</strong> -u root -p tm &lt; tm_20060101.sql<br />
(win os):<span style="color: #ff0000">mysql.exe -uroot -ptm&nbsp;--default-character-set=utf8 &lt; tm_20060101.sql</span><br />
从压缩文件直接恢复：<br />
#gunzip &lt; tm_20060101.sql.gz | <strong style="color: black; background-color: #ffff66">mysql</strong> -u root -p tm<br />
<div>Q：如何启动和关闭<strong style="color: black; background-color: #ffff66">mysql</strong>?<br />
A：linux下：比如我的<strong style="color: black; background-color: #ffff66">mysql</strong>是用源码方式安装在/usr/local/<strong style="color: black; background-color: #ffff66">mysql</strong><br />
自动：将/usr/local/<strong style="color: black; background-color: #ffff66">mysql</strong>/share/<strong style="color: black; background-color: #ffff66">mysql</strong>/<strong style="color: black; background-color: #ffff66">mysql</strong>.server拷贝到/etc/rc.d/init.d/下，然后<br />
chkconfig --add <strong style="color: black; background-color: #ffff66">mysql</strong>.server就可以开机就启动<strong style="color: black; background-color: #ffff66">mysql</strong>服务了。<br />
手动：以root身份执行/usr/local/<strong style="color: black; background-color: #ffff66">mysql</strong>/bin/mysqld_safe --user=<strong style="color: black; background-color: #ffff66">mysql</strong><br />
windows下：<br />
自动：<br />
用cmd方式，到<strong style="color: black; background-color: #ffff66">mysql</strong>安装路径的bin文件夹下，执行：mysqld-nt --install<br />
手动：直接到到<strong style="color: black; background-color: #ffff66">mysql</strong>安装路径的bin文件夹下执行net start <strong style="color: black; background-color: #ffff66">mysql</strong>即可。<br />
如果不想让<strong style="color: black; background-color: #ffff66">mysql</strong>在计算机启动时候就启动服务，执行：mysqld-nt --remove<br />
也可以在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services中删除对应服务并重启计算机。<br />
关闭<strong style="color: black; background-color: #ffff66">mysql</strong>：mysqladmin -uroot -p shutdown<br />
启动<strong style="color: black; background-color: #ffff66">mysql</strong>：<br />
mysqld-nt --install<br />
net start <strong style="color: black; background-color: #ffff66">mysql</strong></div>
<div>安装完后，从win下用<strong style="color: black; background-color: #ffff66">mysql</strong>-odbc连接时，出现</div>
<div>- Client does not support authentication protocol requested by server; consider upgrading <strong style="color: black; background-color: #ffff66">MySQL</strong> client<br />
经查：<br />
A：你使用的数据库是4.1以上，用命令行连接<strong style="color: black; background-color: #ffff66">MySQL</strong>数据库后，执行下面的命令：<br />
UPDATE <strong style="color: black; background-color: #ffff66">mysql</strong>.user SET password=OLD_PASSWORD("your_password") WHERE Host="your_host" AND User="your_username" ;<br />
即可解决。<br />
<br />
your_password：改成你连接数据库的密码，比如 123<br />
your_host：改成你连接数据库的主机，如果是本地的话，就是localhost<br />
your_username：改成你连接数据库的用户，比如 root</div>
<img src ="http://www.blogjava.net/void241/aggbug/216007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/void241/" target="_blank">void</a> 2008-07-19 12:21 <a href="http://www.blogjava.net/void241/archive/2008/07/19/216007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL 备份和恢复</title><link>http://www.blogjava.net/void241/archive/2008/07/19/216006.html</link><dc:creator>void</dc:creator><author>void</author><pubDate>Sat, 19 Jul 2008 04:21:00 GMT</pubDate><guid>http://www.blogjava.net/void241/archive/2008/07/19/216006.html</guid><wfw:comment>http://www.blogjava.net/void241/comments/216006.html</wfw:comment><comments>http://www.blogjava.net/void241/archive/2008/07/19/216006.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/void241/comments/commentRss/216006.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/void241/services/trackbacks/216006.html</trackback:ping><description><![CDATA[<p>本文讨论 MySQL 的备份和恢复机制，以及如何维护数据表，包括最主要的两种表类型：<code><font face="NSimsun">MyISAM</font></code> 和 <code><font face="NSimsun">Innodb</font></code>，文中设计的 MySQL 版本为 5.0.22。</p>
<p>目前 MySQL 支持的免费备份工具有：<code><font face="NSimsun">mysqldump、mysqlhotcopy</font></code>，还可以用 SQL 语法进行备份：<code><font face="NSimsun">BACKUP TABLE</font></code> 或者 <code><font face="NSimsun">SELECT INTO OUTFILE</font></code>，又或者备份<code><font face="NSimsun">二进制日志（binlog）</font></code>，还可以是<code><font face="NSimsun">直接拷贝数据文件和相关的配置文件</font></code>。MyISAM 表是保存成文件的形式，因此相对比较容易备份，上面提到的几种方法都可以使用。<code><font face="NSimsun">Innodb</font></code> 所有的表都保存在同一个数据文件 <code><font face="NSimsun">ibdata1</font></code> 中（也可能是多个文件，或者是独立的表空间文件），相对来说比较不好备份，免费的方案可以是<code><font face="NSimsun">拷贝数据文件</font></code>、<code><font face="NSimsun">备份 binlog</font></code>，或者用 <code><font face="NSimsun">mysqldump</font></code>。</p>
<h3>1、mysqldump</h3>
<h4>1.1 备份</h4>
<p><code><font face="NSimsun">mysqldump</font></code> 是采用SQL级别的备份机制，它将数据表导成 SQL 脚本文件，在不同的 MySQL 版本之间升级时相对比较合适，这也是最常用的备份方法。<br />
现在来讲一下 <code><font face="NSimsun">mysqldump</font></code> 的一些主要参数：</p>
<ul type="1">
    <li>--compatible=name
    <p>它告诉 mysqldump，导出的数据将和哪种数据库或哪个旧版本的 MySQL 服务器相兼容。值可以为 <code><font face="NSimsun">ansi、mysql323、mysql40、postgresql、oracle、mssql、db2、maxdb、no_key_options、no_tables_options、no_field_options</font></code> 等，要使用几个值，用逗号将它们隔开。当然了，它并不保证能完全兼容，而是尽量兼容。</p>
    <li>--complete-insert，-c
    <p>导出的数据采用包含字段名的完整 <code><font face="NSimsun">INSERT</font></code> 方式，也就是把所有的值都写在一行。这么做能提高插入效率，但是可能会受到 <code><font face="NSimsun">max_allowed_packet</font></code> 参数的影响而导致插入失败。因此，需要谨慎使用该参数，至少我不推荐。</p>
    <li>--default-character-set=charset
    <p>指定导出数据时采用何种字符集，如果数据表不是采用默认的 <code><font face="NSimsun">latin1</font></code> 字符集的话，那么导出时必须指定该选项，否则再次导入数据后将产生乱码问题。</p>
    <li>--disable-keys
    <p>告诉 <code><font face="NSimsun">mysqldump</font></code> 在 <code><font face="NSimsun">INSERT</font></code> 语句的开头和结尾增加 <code><font face="NSimsun">/*!40000 ALTER TABLE table DISABLE KEYS */;</font></code> 和 <code><font face="NSimsun">/*!40000 ALTER TABLE table ENABLE KEYS */;</font></code> 语句，这能大大提高插入语句的速度，因为它是在插入完所有数据后才重建索引的。该选项只适合 <code><font face="NSimsun">MyISAM</font></code> 表。</p>
    <li>--extended-insert = true|false
    <p>默认情况下，<code><font face="NSimsun">mysqldump</font></code> 开启 <code><font face="NSimsun">--complete-insert</font></code> 模式，因此不想用它的的话，就使用本选项，设定它的值为 <code><font face="NSimsun">false</font></code> 即可。</p>
    <li>--hex-blob
    <p>使用十六进制格式导出二进制字符串字段。如果有二进制数据就必须使用本选项。影响到的字段类型有 <code><font face="NSimsun">BINARY、VARBINARY、BLOB</font></code>。</p>
    <li>--lock-all-tables，-x
    <p>在开始导出之前，提交请求锁定所有数据库中的所有表，以保证数据的一致性。这是一个全局读锁，并且自动关闭 <code><font face="NSimsun">--single-transaction</font></code> 和 <code><font face="NSimsun">--lock-tables</font></code> 选项。</p>
    <li>--lock-tables
    <p>它和 <code><font face="NSimsun">--lock-all-tables</font></code> 类似，不过是锁定当前导出的数据表，而不是一下子锁定全部库下的表。本选项只适用于 <code><font face="NSimsun">MyISAM</font></code> 表，如果是 <code><font face="NSimsun">Innodb</font></code> 表可以用 <code><font face="NSimsun">--single-transaction</font></code> 选项。</p>
    <li>--no-create-info，-t
    <p>只导出数据，而不添加 <code><font face="NSimsun">CREATE TABLE</font></code> 语句。</p>
    <li>--no-data，-d
    <p>不导出任何数据，只导出数据库表结构。</p>
    <li>--opt
    <p>这只是一个快捷选项，等同于同时添加 <code><font face="NSimsun">--add-drop-tables --add-locking --create-option --disable-keys --extended-insert --lock-tables --quick --set-charset</font></code> 选项。本选项能让 <code><font face="NSimsun">mysqldump</font></code> 很快的导出数据，并且导出的数据能很快导回。该选项默认开启，但可以用 <code><font face="NSimsun">--skip-opt</font></code> 禁用。注意，如果运行 <code><font face="NSimsun">mysqldump</font></code> 没有指定 <code><font face="NSimsun">--quick</font></code> 或 <code><font face="NSimsun">--opt</font></code> 选项，则会将整个结果集放在内存中。如果导出大数据库的话可能会出现问题。</p>
    <li>--quick，-q
    <p>该选项在导出大表时很有用，它强制 <code><font face="NSimsun">mysqldump</font></code> 从服务器查询取得记录直接输出而不是取得所有记录后将它们缓存到内存中。</p>
    <li>--routines，-R
    <p>导出存储过程以及自定义函数。</p>
    <li>--single-transaction
    <p>该选项在导出数据之前提交一个 <code><font face="NSimsun">BEGIN</font></code> SQL语句，<code><font face="NSimsun">BEGIN</font></code> 不会阻塞任何应用程序且能保证导出时数据库的一致性状态。它只适用于事务表，例如 <code><font face="NSimsun">InnoDB</font></code> 和 <code><font face="NSimsun">BDB</font></code>。<br />
    本选项和 <code><font face="NSimsun">--lock-tables</font></code> 选项是互斥的，因为 <code><font face="NSimsun">LOCK TABLES</font></code> 会使任何挂起的事务隐含提交。<br />
    要想导出大表的话，应结合使用 <code><font face="NSimsun">--quick</font></code> 选项。</p>
    <li>--triggers
    <p>同时导出触发器。该选项默认启用，用 <code><font face="NSimsun">--skip-triggers</font></code> 禁用它。</p>
    </li>
</ul>
<p>其他参数详情请参考手册，我通常使用以下 SQL 来备份 <code><font face="NSimsun">MyISAM</font></code> 表：</p>
<pre>/usr/local/mysql/bin/mysqldump -uyejr -pyejr \
--default-character-set=utf8 --opt --extended-insert=false \
--triggers -R --hex-blob -x db_name &gt; db_name.sql</pre>
<p>使用以下 SQL 来备份 <code><font face="NSimsun">Innodb</font></code> 表：</p>
<pre>/usr/local/mysql/bin/mysqldump -uyejr -pyejr \
--default-character-set=utf8 --opt --extended-insert=false \
--triggers -R --hex-blob --single-transaction db_name &gt; db_name.sql</pre>
<p>另外，如果想要实现在线备份，还可以使用 <code><font face="NSimsun">--master-data</font></code> 参数来实现，如下：</p>
<pre>/usr/local/mysql/bin/mysqldump -uyejr -pyejr \
--default-character-set=utf8 --opt --master-data=1 \
--single-transaction --flush-logs db_name &gt; db_name.sql</pre>
<p>它只是在一开始的瞬间请求锁表，然后就刷新binlog了，而后在导出的文件中加入<code><font face="NSimsun">CHANGE MASTER</font></code> 语句来指定当前备份的binlog位置，如果要把这个文件恢复到slave里去，就可以采用这种方法来做。</p>
<h4>1.2 还原</h4>
<p>用 <code><font face="NSimsun">mysqldump</font></code> 备份出来的文件是一个可以直接倒入的 SQL 脚本，有两种方法可以将数据导入。</p>
<ul type="1">
    <li>直接用 <code><font face="NSimsun">mysql</font></code> 客户端
    <p>例如：</p>
    <pre>/usr/local/mysql/bin/mysql -uyejr -pyejr db_name &lt; db_name.sql</pre>
    <p>&nbsp;</p>
    <li>用 SOURCE 语法
    <p>其实这不是标准的 SQL 语法，而是 <code><font face="NSimsun">mysql</font></code> 客户端提供的功能，例如：</p>
    <pre>SOURCE /tmp/db_name.sql;</pre>
    <p>这里需要指定文件的绝对路径，并且必须是 <code><font face="NSimsun">mysqld</font></code> 运行用户(例如 nobody)有权限读取的文件。</p>
    </li>
</ul>
<h3>2、 mysqlhotcopy</h3>
<h4>2.1 备份</h4>
<p><code><font face="NSimsun">mysqlhotcopy</font></code> 是一个 PERL 程序，最初由Tim Bunce编写。它使用 <code><font face="NSimsun">LOCK TABLES、FLUSH TABLES</font></code> 和 <code><font face="NSimsun">cp</font></code> 或 <code><font face="NSimsun">scp</font></code> 来快速备份数据库。它是备份数据库或单个表的最快的途径，但它只能运行在数据库文件（包括数据表定义文件、数据文件、索引文件）所在的机器上。<code><font face="NSimsun">mysqlhotcopy</font></code> 只能用于备份 <code><font face="NSimsun">MyISAM</font></code>，并且只能运行在 <code><font face="NSimsun">类Unix</font></code> 和 <code><font face="NSimsun">NetWare</font></code> 系统上。</p>
<p><code><font face="NSimsun">mysqlhotcopy</font></code> 支持一次性拷贝多个数据库，同时还支持正则表达。以下是几个例子：</p>
<pre>root#/usr/local/mysql/bin/mysqlhotcopy -h=localhost -u=yejr -p=yejr \
db_name /tmp (把数据库目录 <tt>db_name</tt> 拷贝到 <tt>/tmp</tt> 下)
root#/usr/local/mysql/bin/mysqlhotcopy -h=localhost -u=yejr -p=yejr \
db_name_1 ... db_name_n /tmp
root#/usr/local/mysql/bin/mysqlhotcopy -h=localhost -u=yejr -p=yejr \
db_name./regex/ /tmp</pre>
<p>更详细的使用方法请查看手册，或者调用下面的命令来查看 <code><font face="NSimsun">mysqlhotcopy</font></code> 的帮助：</p>
<pre>perldoc /usr/local/mysql/bin/mysqlhotcopy</pre>
<p>注意，想要使用 <code><font face="NSimsun">mysqlhotcopy</font></code>，必须要有 <code><font face="NSimsun">SELECT、RELOAD(要执行 FLUSH TABLES)</font></code> 权限，并且还必须要能够有读取 <tt><font face="NSimsun">datadir/db_name</font></tt> 目录的权限。</p>
<h4>2.2 还原</h4>
<p><code><font face="NSimsun">mysqlhotcopy</font></code> 备份出来的是整个数据库目录，使用时可以直接拷贝到 <code><font face="NSimsun">mysqld</font></code> 指定的 <tt><font face="NSimsun">datadir</font></tt> (在这里是 <tt><font face="NSimsun">/usr/local/mysql/data/</font></tt>)目录下即可，同时要注意权限的问题，如下例：</p>
<pre>root#cp -rf db_name /usr/local/mysql/data/
root#chown -R nobody:nobody /usr/local/mysql/data/ (将 db_name 目录的属主改成 <code>mysqld</code> 运行用户)</pre>
<p>&nbsp;</p>
<h3>3、 SQL 语法备份</h3>
<h4>3.1 备份</h4>
<p><code><font face="NSimsun">BACKUP TABLE</font></code> 语法其实和 <code><font face="NSimsun">mysqlhotcopy</font></code> 的工作原理差不多，都是锁表，然后拷贝数据文件。它能实现在线备份，但是效果不理想，因此不推荐使用。它只拷贝表结构文件和数据文件，不同时拷贝索引文件，因此恢复时比较慢。<br />
例子：</p>
<pre>BACK TABLE tbl_name TO '/tmp/db_name/';</pre>
<p>注意，必须要有 <code><font face="NSimsun">FILE</font></code> 权限才能执行本SQL，并且目录 <tt><font face="NSimsun">/tmp/db_name/</font></tt> 必须能被 <code><font face="NSimsun">mysqld</font></code> 用户可写，导出的文件不能覆盖已经存在的文件，以避免安全问题。</p>
<p><code><font face="NSimsun">SELECT INTO OUTFILE</font></code> 则是把数据导出来成为普通的文本文件，可以自定义字段间隔的方式，方便处理这些数据。<br />
例子：</p>
<pre>SELECT * INTO OUTFILE '/tmp/db_name/tbl_name.txt' FROM tbl_name;</pre>
<p>注意，必须要有 <code><font face="NSimsun">FILE</font></code> 权限才能执行本SQL，并且文件 <tt><font face="NSimsun">/tmp/db_name/tbl_name.txt</font></tt> 必须能被 <code><font face="NSimsun">mysqld</font></code> 用户可写，导出的文件不能覆盖已经存在的文件，以避免安全问题。</p>
<h4>3.2 恢复</h4>
<p>用 <code><font face="NSimsun">BACKUP TABLE</font></code> 方法备份出来的文件，可以运行 <code><font face="NSimsun">RESTORE TABLE</font></code> 语句来恢复数据表。<br />
例子：</p>
<pre>RESTORE TABLE FROM '/tmp/db_name/';</pre>
<p>权限要求类似上面所述。</p>
<p>用 <code><font face="NSimsun">SELECT INTO OUTFILE</font></code> 方法备份出来的文件，可以运行 <code><font face="NSimsun">LOAD DATA INFILE</font></code> 语句来恢复数据表。<br />
例子：</p>
<pre>LOAD DATA INFILE '/tmp/db_name/tbl_name.txt' INTO TABLE tbl_name;</pre>
<p>权限要求类似上面所述。倒入数据之前，数据表要已经存在才行。如果担心数据会发生重复，可以增加 <code><font face="NSimsun">REPLACE</font></code> 关键字来替换已有记录或者用 <code><font face="NSimsun">IGNORE</font></code> 关键字来忽略他们。</p>
<h3>4、 启用二进制日志(binlog)</h3>
<p>采用 <code><font face="NSimsun">binlog</font></code> 的方法相对来说更灵活，省心省力，而且还可以支持增量备份。</p>
<p>启用 <code><font face="NSimsun">binlog</font></code> 时必须要重启 <code><font face="NSimsun">mysqld</font></code>。首先，关闭 <code><font face="NSimsun">mysqld</font></code>，打开 <code><font face="NSimsun">my.cnf</font></code>，加入以下几行：</p>
<pre>server-id = 1
log-bin  = binlog
log-bin-index = binlog.index</pre>
<p>然后启动 <code><font face="NSimsun">mysqld</font></code> 就可以了。运行过程中会产生 <code><font face="NSimsun">binlog.000001</font></code> 以及 <code><font face="NSimsun">binlog.index</font></code>，前面的文件是 <code><font face="NSimsun">mysqld</font></code> 记录所有对数据的更新操作，后面的文件则是所有 <code><font face="NSimsun">binlog</font></code> 的索引，都不能轻易删除。关于 <code><font face="NSimsun">binlog</font></code> 的信息请查看手册。</p>
<p>需要备份时，可以先执行一下 SQL 语句，让 <code><font face="NSimsun">mysqld</font></code> 终止对当前 <code><font face="NSimsun">binlog</font></code> 的写入，就可以把文件直接备份，这样的话就能达到增量备份的目的了：</p>
<pre>FLUSH LOGS;</pre>
<p>如果是备份复制系统中的从服务器，还应该备份 <tt><font face="NSimsun">master.info</font></tt> 和 <tt><font face="NSimsun">relay-log.info</font></tt> 文件。</p>
<p>备份出来的 <code><font face="NSimsun">binlog</font></code> 文件可以用 MySQL 提供的工具 <code><font face="NSimsun">mysqlbinlog</font></code> 来查看，如：</p>
<pre>/usr/local/mysql/bin/mysqlbinlog /tmp/binlog.000001</pre>
<p>该工具允许你显示指定的数据库下的所有 SQL 语句，并且还可以限定时间范围，相当的方便，详细的请查看手册。</p>
<p>恢复时，可以采用类似以下语句来做到：</p>
<pre>/usr/local/mysql/bin/mysqlbinlog /tmp/binlog.000001 | mysql -uyejr -pyejr db_name</pre>
<p>把 <code><font face="NSimsun">mysqlbinlog</font></code> 输出的 SQL 语句直接作为输入来执行它。</p>
<p>如果你有空闲的机器，不妨采用这种方式来备份。由于作为 <code><font face="NSimsun">slave</font></code> 的机器性能要求相对不是那么高，因此成本低，用低成本就能实现增量备份而且还能分担一部分数据查询压力，何乐而不为呢？</p>
<h3>5、 直接备份数据文件</h3>
<p>相较前几种方法，备份数据文件最为直接、快速、方便，缺点是基本上不能实现增量备份。为了保证数据的一致性，需要在靠背文件前，执行以下 SQL 语句：</p>
<pre>FLUSH TABLES WITH READ LOCK;</pre>
<p>也就是把内存中的数据都刷新到磁盘中，同时锁定数据表，以保证拷贝过程中不会有新的数据写入。这种方法备份出来的数据恢复也很简单，直接拷贝回原来的数据库目录下即可。</p>
<p>注意，对于 <code><font face="NSimsun">Innodb</font></code> 类型表来说，还需要备份其日志文件，即 <code><font face="NSimsun">ib_logfile*</font></code> 文件。因为当 <code><font face="NSimsun">Innodb</font></code> 表损坏时，就可以依靠这些日志文件来恢复。</p>
<h3>6、 备份策略</h3>
<p>对于中等级别业务量的系统来说，备份策略可以这么定：第一次全量备份，每天一次增量备份，每周再做一次全量备份，如此一直重复。而对于重要的且繁忙的系统来说，则可能需要每天一次全量备份，每小时一次增量备份，甚至更频繁。为了不影响线上业务，实现在线备份，并且能增量备份，最好的办法就是采用主从复制机制(<code><font face="NSimsun">replication</font></code>)，在 <code><font face="NSimsun">slave</font></code> 机器上做备份。</p>
<h3>7、 数据维护和灾难恢复</h3>
<p>作为一名DBA(我目前还不是，呵呵)，最重要的工作内容之一是保证数据表能安全、稳定、高速使用。因此，需要定期维护你的数据表。以下 SQL 语句就很有用：</p>
<pre>CHECK TABLE 或 REPAIR TABLE，检查或维护 MyISAM 表
OPTIMIZE TABLE，优化 MyISAM 表
ANALYZE TABLE，分析 MyISAM 表</pre>
<p>当然了，上面这些命令起始都可以通过工具 <code><font face="NSimsun">myisamchk</font></code> 来完成，在这里不作详述。</p>
<p><code><font face="NSimsun">Innodb</font></code> 表则可以通过执行以下语句来整理碎片，提高索引速度：</p>
<pre>ALTER TABLE tbl_name ENGINE = Innodb;</pre>
<p>这其实是一个 <code><font face="NSimsun">NULL</font></code> 操作，表面上看什么也不做，实际上重新整理碎片了。</p>
<p>通常使用的 <code><font face="NSimsun">MyISAM</font></code> 表可以用上面提到的恢复方法来完成。如果是索引坏了，可以用 <code><font face="NSimsun">myisamchk</font></code> 工具来重建索引。而对于 <code><font face="NSimsun">Innodb</font></code> 表来说，就没这么直接了，因为它把所有的表都保存在一个表空间了。不过 <code><font face="NSimsun">Innodb</font></code> 有一个检查机制叫 <code><font face="NSimsun">模糊检查点</font></code>，只要保存了日志文件，就能根据日志文件来修复错误。可以在 <tt><font face="NSimsun">my.cnf</font></tt> 文件中，增加以下参数，让 <code><font face="NSimsun">mysqld</font></code> 在启动时自动检查日志文件：</p>
<pre>innodb_force_recovery = 4</pre>
<p>关于该参数的信息请查看手册。</p>
<h3>8、 总结</h3>
<p>做好数据备份，定只好合适的备份策略，这是一个DBA所做事情的一小部分，万事开头难，就从现在开始吧！</p>
<img src ="http://www.blogjava.net/void241/aggbug/216006.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/void241/" target="_blank">void</a> 2008-07-19 12:21 <a href="http://www.blogjava.net/void241/archive/2008/07/19/216006.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql 新功能 －－ 分区</title><link>http://www.blogjava.net/void241/archive/2008/07/19/216003.html</link><dc:creator>void</dc:creator><author>void</author><pubDate>Sat, 19 Jul 2008 04:17:00 GMT</pubDate><guid>http://www.blogjava.net/void241/archive/2008/07/19/216003.html</guid><wfw:comment>http://www.blogjava.net/void241/comments/216003.html</wfw:comment><comments>http://www.blogjava.net/void241/archive/2008/07/19/216003.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/void241/comments/commentRss/216003.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/void241/services/trackbacks/216003.html</trackback:ping><description><![CDATA[<h3>错误的按日期分区例子</h3>
<p>最直观的方法，就是直接用年月日这种日期格式来进行常规的分区：</p>
<div class="igBar"><span><a href="http://www.ooso.net/index.php/archives/217#">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div>
<div class="code">
<ol>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">mysql&gt; create table rms <span style="font-weight: bold; color: #006600">(</span>d date<span style="font-weight: bold; color: #006600">)</span></div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>partition</span> by range <span style="font-weight: bold; color: #006600">(</span>d<span style="font-weight: bold; color: #006600">)</span></div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span style="font-weight: bold; color: #006600">(</span>partition p0 values less than <span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'1995-01-01'</span><span style="font-weight: bold; color: #006600">)</span>,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>partition</span> p1 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'2010-01-01'</span><span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span>;</div>
    </li>
</ol>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>上面的例子中，就是直接用"Y-m-d"的格式来对一个table进行分区，可惜想当然往往不能奏效，会得到一个错误信息:</p>
<blockquote>
<p>ERROR 1064 (42000): VALUES value must be of same type as partition function near '),<br />
partition p1 VALUES LESS THAN ('2010-01-01'))' at line 3</p>
</blockquote>
<p>上述分区方式没有成功，而且明显的不经济，老练的DBA会用整型数值来进行分区：</p>
<div class="igBar"><span><a href="http://www.ooso.net/index.php/archives/217#">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div>
<div class="code">
<ol>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">mysql&gt; CREATE TABLE part_date1</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span style="font-weight: bold; color: #006600">(</span> c1 int default NULL,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>c2</span> varchar<span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">30</span><span style="font-weight: bold; color: #006600">)</span> default NULL,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>c3</span> date default NULL<span style="font-weight: bold; color: #006600">)</span> engine=myisam</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>partition</span> by range <span style="font-weight: bold; color: #006600">(</span>cast<span style="font-weight: bold; color: #006600">(</span>date_format<span style="font-weight: bold; color: #006600">(</span>c3,<span style="color: #cc0000">'%Y%m%d'</span><span style="font-weight: bold; color: #006600">)</span> as signed<span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span></div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span style="font-weight: bold; color: #006600">(</span>PARTITION p0 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">19950101</span><span style="font-weight: bold; color: #006600">)</span>,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p1 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">19960101</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p2 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">19970101</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p3 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">19980101</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p4 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">19990101</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p5 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">20000101</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p6 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">20010101</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p7 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">20020101</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p8 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">20030101</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p9 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">20040101</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p10 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">20100101</span><span style="font-weight: bold; color: #006600">)</span>,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p11 VALUES LESS THAN MAXVALUE <span style="font-weight: bold; color: #006600">)</span>;</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">Query OK, <span style="color: #800000">0</span> rows affected <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">0</span>.<span style="color: #800000">01</span> sec<span style="font-weight: bold; color: #006600">)</span></div>
    </li>
</ol>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>搞定？接着往下分析</p>
<p>&nbsp;</p>
<div class="igBar"><span><a href="http://www.ooso.net/index.php/archives/217#">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div>
<div class="code">
<ol>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">mysql&gt; explain partitions</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>select</span> count<span style="font-weight: bold; color: #006600">(</span>*<span style="font-weight: bold; color: #006600">)</span> from part_date1 where</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>c3</span>&gt; date <span style="color: #cc0000">'1995-01-01'</span> and c3 &lt;date <span style="color: #cc0000">'1995-12-31'</span>\G</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">*************************** <span style="color: #800000">1</span>. <span>row</span> ***************************</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">id: <span style="color: #800000">1</span></div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">select_type: SIMPLE</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">table: part_date1</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">partitions: p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">type: ALL</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">possible_keys: NULL</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">key: NULL</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">key_len: NULL</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">ref: NULL</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">rows: <span style="color: #800000">8100000</span></div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">Extra: Using where</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal"><span style="color: #800000">1</span> row in set <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">0</span>.<span style="color: #800000">00</span> sec<span style="font-weight: bold; color: #006600">)</span></div>
    </li>
</ol>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>万恶的mysql居然对上面的sql使用全表扫描，而不是按照我们的日期分区分块查询。原文中解释到<a href="http://www.ooso.net/index.php/archives/category/mysql/">MYSQL</a>的优化器并不认这种日期形式的分区，花了大量的篇幅来引诱俺走上歧路，过分。</p>
<h3>正确的日期分区例子</h3>
<p>mysql优化器支持以下两种内置的日期函数进行分区：</p>
<ul>
    <li>TO_DAYS()
    <li>YEAR() </li>
</ul>
<p>看个例子：</p>
<div class="igBar"><span><a href="http://www.ooso.net/index.php/archives/217#">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div>
<div class="code">
<ol>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">mysql&gt; CREATE TABLE part_date3</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span style="font-weight: bold; color: #006600">(</span> c1 int default NULL,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>c2</span> varchar<span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">30</span><span style="font-weight: bold; color: #006600">)</span> default NULL,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>c3</span> date default NULL<span style="font-weight: bold; color: #006600">)</span> engine=myisam</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>partition</span> by range <span style="font-weight: bold; color: #006600">(</span>to_days<span style="font-weight: bold; color: #006600">(</span>c3<span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span></div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span style="font-weight: bold; color: #006600">(</span>PARTITION p0 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span>to_days<span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'1995-01-01'</span><span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span>,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p1 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span>to_days<span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'1996-01-01'</span><span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p2 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span>to_days<span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'1997-01-01'</span><span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p3 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span>to_days<span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'1998-01-01'</span><span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p4 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span>to_days<span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'1999-01-01'</span><span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p5 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span>to_days<span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'2000-01-01'</span><span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p6 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span>to_days<span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'2001-01-01'</span><span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p7 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span>to_days<span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'2002-01-01'</span><span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p8 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span>to_days<span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'2003-01-01'</span><span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p9 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span>to_days<span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'2004-01-01'</span><span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span> ,</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p10 VALUES LESS THAN <span style="font-weight: bold; color: #006600">(</span>to_days<span style="font-weight: bold; color: #006600">(</span><span style="color: #cc0000">'2010-01-01'</span><span style="font-weight: bold; color: #006600">)</span><span style="font-weight: bold; color: #006600">)</span>,</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>PARTITION</span> p11 VALUES LESS THAN MAXVALUE <span style="font-weight: bold; color: #006600">)</span>;</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">Query OK, <span style="color: #800000">0</span> rows affected <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">0</span>.<span style="color: #800000">00</span> sec<span style="font-weight: bold; color: #006600">)</span></div>
    </li>
</ol>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>以to_days()函数分区成功，我们分析一下看看：</p>
<div class="igBar"><span><a href="http://www.ooso.net/index.php/archives/217#">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div>
<div class="code">
<ol>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">mysql&gt; explain partitions</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>select</span> count<span style="font-weight: bold; color: #006600">(</span>*<span style="font-weight: bold; color: #006600">)</span> from part_date3 where</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>c3</span>&gt; date <span style="color: #cc0000">'1995-01-01'</span> and c3 &lt;date <span style="color: #cc0000">'1995-12-31'</span>\G</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">*************************** <span style="color: #800000">1</span>. <span>row</span> ***************************</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">id: <span style="color: #800000">1</span></div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">select_type: SIMPLE</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">table: part_date3</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">partitions: p1</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">type: ALL</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">possible_keys: NULL</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">key: NULL</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">key_len: NULL</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">ref: NULL</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">rows: <span style="color: #800000">808431</span></div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">Extra: Using where</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal"><span style="color: #800000">1</span> row in set <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">0</span>.<span style="color: #800000">00</span> sec<span style="font-weight: bold; color: #006600">)</span></div>
    </li>
</ol>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>可以看到，<a href="http://www.ooso.net/index.php/archives/category/mysql/">mysql</a>优化器这次不负众望，仅仅在p1分区进行查询。在这种情况下查询，真的能够带来提升查询效率么？下面分别对这次建立的part_date3和之前分区失败的part_date1做一个查询对比：</p>
<div class="igBar"><span><a href="http://www.ooso.net/index.php/archives/217#">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div>
<div class="code">
<ol>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">mysql&gt; select count<span style="font-weight: bold; color: #006600">(</span>*<span style="font-weight: bold; color: #006600">)</span> from part_date3 where</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">-&gt; <span>c3</span>&gt; date <span style="color: #cc0000">'1995-01-01'</span> and c3 &lt;date <span style="color: #cc0000">'1995-12-31'</span>;</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">+----------+</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">| count<span style="font-weight: bold; color: #006600">(</span>*<span style="font-weight: bold; color: #006600">)</span> |</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">+----------+</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">| <span style="color: #800000">805114</span> |</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">+----------+</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal"><span style="color: #800000">1</span> row in set <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">4</span>.<span style="color: #800000">11</span> sec<span style="font-weight: bold; color: #006600">)</span></div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal"></div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">mysql&gt; select count<span style="font-weight: bold; color: #006600">(</span>*<span style="font-weight: bold; color: #006600">)</span> from part_date1 where</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">-&gt; <span>c3</span>&gt; date <span style="color: #cc0000">'1995-01-01'</span> and c3 &lt;date <span style="color: #cc0000">'1995-12-31'</span>;</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">+----------+</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">| count<span style="font-weight: bold; color: #006600">(</span>*<span style="font-weight: bold; color: #006600">)</span> |</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">+----------+</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal">| <span style="color: #800000">805114</span> |</div>
    <li style="font-weight: bold; color: #26536a">
    <div style="font-weight: normal">+----------+</div>
    <li style="font-weight: normal; color: #3a6a8b; font-style: normal">
    <div style="font-weight: normal"><span style="color: #800000">1</span> row in set <span style="font-weight: bold; color: #006600">(</span><span style="color: #800000">40</span>.<span style="color: #800000">33</span> sec<span style="font-weight: bold; color: #006600">)</span></div>
    </li>
</ol>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>可以看到，分区正确的话query花费时间为4秒，而分区错误则花费时间40秒（相当于没有分区），效率有90％的提升！所以我们千万要正确的使用分区功能，分区后务必用explain验证，这样才能获得真正的性能提升。</p>
<img src ="http://www.blogjava.net/void241/aggbug/216003.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/void241/" target="_blank">void</a> 2008-07-19 12:17 <a href="http://www.blogjava.net/void241/archive/2008/07/19/216003.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>优化MySQL数据库性能的八大“妙手”</title><link>http://www.blogjava.net/void241/archive/2008/07/19/216002.html</link><dc:creator>void</dc:creator><author>void</author><pubDate>Sat, 19 Jul 2008 04:16:00 GMT</pubDate><guid>http://www.blogjava.net/void241/archive/2008/07/19/216002.html</guid><wfw:comment>http://www.blogjava.net/void241/comments/216002.html</wfw:comment><comments>http://www.blogjava.net/void241/archive/2008/07/19/216002.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/void241/comments/commentRss/216002.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/void241/services/trackbacks/216002.html</trackback:ping><description><![CDATA[<p><strong>1、选取最适用的字段属性<br />
<br />
</strong>　　MySQL可以很好的支持大数据量的存取，但是一般说来，数据库中的表越小，在它上面执行的查询也就会越快。因此，在创建表的时候，为了获得更好的性能，我们可以将表中字段的宽度设得尽可能小。例如，在定义邮政编码这个字段时，如果将其设置为CHAR(255),显然给数据库增加了不必要的空间，甚至使用VARCHAR这种类型也是多余的，因为CHAR(6)就可以很好的完成任务了。同样的，如果可以的话，我们应该使用MEDIUMINT而不是BIGIN来定义整型字段。<br />
<br />
　　另外一个提高效率的方法是在可能的情况下，应该尽量把字段设置为NOT NULL，这样在将来执行查询的时候，数据库不用去比较NULL值。<br />
<br />
　　对于某些文本字段，例如&#8220;省份&#8221;或者&#8220;性别&#8221;，我们可以将它们定义为ENUM类型。因为在MySQL中，ENUM类型被当作数值型数据来处理，而数值型数据被处理起来的速度要比文本类型快得多。这样，我们又可以提高数据库的性能。<br />
<br />
　　<strong>2、使用连接（JOIN）来代替子查询(Sub-Queries)</strong><br />
<br />
　　MySQL从4.1开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果，然后把这个结果作为过滤条件用在另一个查询中。例如，我们要将客户基本信息表中没有任何订单的客户删除掉，就可以利用子查询先从销售信息表中将所有发出订单的客户ID取出来，然后将结果传递给主查询，如下所示：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">DELETE FROM customerinfo<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )</span></div>
</div>
<p>使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作，同时也可以避免事务或者表锁死，并且写起来也很容易。但是，有些情况下，子查询可以被更有效率的连接（JOIN）.. 替代。例如，假设我们要将所有没有订单记录的用户取出来，可以用下面这个查询完成：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">SELECT </span><span style="color: #000000">*</span><span style="color: #000000"> FROM customerinfo<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )</span></div>
</div>
<p>如果使用连接（JOIN）.. 来完成这个查询工作，速度将会快很多。尤其是当salesinfo表中对CustomerID建有索引的话，性能将会更好，查询如下：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">SELECT </span><span style="color: #000000">*</span><span style="color: #000000"> FROM customerinfo <br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />LEFT JOIN salesinfoON customerinfo.CustomerID</span><span style="color: #000000">=</span><span style="color: #000000">salesinfo. <br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />CustomerID <br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />WHERE salesinfo.CustomerID IS NULL&nbsp;&nbsp;<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
</div>
<p>连接（JOIN）.. 之所以更有效率一些，是因为 MySQL不需要在内存中创建临时表来完成这个逻辑上的需要两个步骤的查询工作。<br />
<br />
<strong>3、使用联合(UNION)来代替手动创建的临时表<br />
<br />
</strong>　　MySQL 从 4.0 的版本开始支持 UNION 查询，它可以把需要使用临时表的两条或更多的 SELECT 查询合并的一个查询中。在客户端的查询会话结束的时候，临时表会被自动删除，从而保证数据库整齐、高效。使用 UNION 来创建查询的时候，我们只需要用 UNION作为关键字把多个 SELECT 语句连接起来就可以了，要注意的是所有 SELECT 语句中的字段数目要想同。下面的例子就演示了一个使用 UNION的查询。</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">SELECT Name, Phone FROM client<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />UNION<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />SELECT Name, BirthDate FROM author<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />UNION<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />SELECT Name, Supplier FROM product</span></div>
</div>
<p>　<strong>4、事务</strong><br />
<br />
　　尽管我们可以使用子查询（Sub-Queries）、连接（JOIN）和联合（UNION）来创建各种各样的查询，但不是所有的数据库操作都可以只用一条或少数几条SQL语句就可以完成的。更多的时候是需要用到一系列的语句来完成某种工作。但是在这种情况下，当这个语句块中的某一条语句运行出错的时候，整个语句块的操作就会变得不确定起来。设想一下，要把某个数据同时插入两个相关联的表中，可能会出现这样的情况：第一个表中成功更新后，数据库突然出现意外状况，造成第二个表中的操作没有完成，这样，就会造成数据的不完整，甚至会破坏数据库中的数据。要避免这种情况，就应该使用事务，它的作用是：要么语句块中每条语句都操作成功，要么都失败。换句话说，就是可以保持数据库中数据的一致性和完整性。事物以BEGIN 关键字开始，COMMIT关键字结束。在这之间的一条SQL操作失败，那么，ROLLBACK命令就可以把数据库恢复到BEGIN开始之前的状态。</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">BEGIN;<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />INSERT INTO salesinfo SET CustomerID</span><span style="color: #000000">=</span><span style="color: #000000">14</span><span style="color: #000000">;<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />UPDATE inventory SET Quantity</span><span style="color: #000000">=</span><span style="color: #000000">11</span><span style="color: #000000"><br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />WHERE item</span><span style="color: #000000">=</span><span style="color: #000000">'</span><span style="color: #000000">book</span><span style="color: #000000">'</span><span style="color: #000000">;<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />COMMIT;</span></div>
</div>
<p>　事务的另一个重要作用是当多个用户同时使用相同的数据源时，它可以利用锁定数据库的方法来为用户提供一种安全的访问方式，这样可以保证用户的操作不被其它的用户所干扰。<br />
<br />
<strong>5、锁定表<br />
<br />
</strong>　　尽管事务是维护数据库完整性的一个非常好的方法，但却因为它的独占性，有时会影响数据库的性能，尤其是在很大的应用系统中。由于在事务执行的过程中，数据库将会被锁定，因此其它的用户请求只能暂时等待直到该事务结束。如果一个数据库系统只有少数几个用户<br />
来使用，事务造成的影响不会成为一个太大的问题；但假设有成千上万的用户同时访问一个数据库系统，例如访问一个电子商务网站，就会产生比较严重的响应延迟。<br />
<br />
　　其实，有些情况下我们可以通过锁定表的方法来获得更好的性能。下面的例子就用锁定表的方法来完成前面一个例子中事务的功能。</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">LOCK TABLE inventory WRITE<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />SELECT Quantity FROM inventory<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />WHEREItem</span><span style="color: #000000">=</span><span style="color: #000000">'</span><span style="color: #000000">book</span><span style="color: #000000">'</span><span style="color: #000000">;<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />...<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />UPDATE inventory SET Quantity</span><span style="color: #000000">=</span><span style="color: #000000">11</span><span style="color: #000000"><br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />WHEREItem</span><span style="color: #000000">=</span><span style="color: #000000">'</span><span style="color: #000000">book</span><span style="color: #000000">'</span><span style="color: #000000">;<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />UNLOCK TABLES</span></div>
</div>
<p>这里，我们用一个 SELECT 语句取出初始数据，通过一些计算，用 UPDATE 语句将新值更新到表中。包含有 WRITE 关键字的 LOCK TABLE 语句可以保证在 UNLOCK TABLES 命令被执行之前，不会有其它的访问来对 inventory 进行插入、更新或者删除的操作。<br />
<br />
　　6、使用外键<br />
<br />
　　锁定表的方法可以维护数据的完整性，但是它却不能保证数据的关联性。这个时候我们就可以使用外键。例如，外键可以保证每一条销售记录都指向某一个存在的客户。在这里，外键可以把customerinfo 表中的CustomerID映射到salesinfo表中CustomerID，任何一条没有合法CustomerID的记录都不会被更新或插入到salesinfo中。</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">CREATE TABLE customerinfo<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />(<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />CustomerID INT NOT NULL ,<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />PRIMARY KEY ( CustomerID )<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />) TYPE </span><span style="color: #000000">=</span><span style="color: #000000"> INNODB;<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />CREATE TABLE salesinfo<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />(<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />SalesID INT NOT NULL,<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />CustomerID INT NOT NULL,<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />PRIMARY KEY(CustomerID, SalesID),<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />FOREIGN KEY (CustomerID) REFERENCES customerinfo<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />(CustomerID) ON DELETECASCADE<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />) TYPE </span><span style="color: #000000">=</span><span style="color: #000000"> INNODB;</span></div>
</div>
<p>注意例子中的参数&#8220;ON DELETE CASCADE&#8221;。该参数保证当 customerinfo 表中的一条客户记录被删除的时候，salesinfo 表中所有与该客户相关的记录也会被自动删除。如果要在 MySQL 中使用外键，一定要记住在创建表的时候将表的类型定义为事务安全表 InnoDB类型。该类型不是 MySQL 表的默认类型。定义的方法是在 CREATE TABLE 语句中加上 TYPE=INNODB。如例中所示。<br />
<br />
　　<strong>7、使用索引</strong><br />
<br />
　　索引是提高数据库性能的常用方法，它可以令数据库服务器以比没有索引快得多的速度检索特定的行，尤其是在查询语句当中包含有MAX(), MIN()和ORDERBY这些命令的时候，性能提高更为明显。那该对哪些字段建立索引呢？一般说来，索引应建立在那些将用于JOIN, WHERE判断和ORDER BY排序的字段上。尽量不要对数据库中某个含有大量重复的值的字段建立索引。对于一个ENUM类型的字段来说，出现大量重复值是很有可能的情况，例如customerinfo中的&#8220;province&#8221;.. 字段，在这样的字段上建立索引将不会有什么帮助；相反，还有可能降低数据库的性能。我们在创建表的时候可以同时创建合适的索引，也可以使用ALTER TABLE或CREATE INDEX在以后创建索引。此外，MySQL<br />
从版本3.23.23开始支持全文索引和搜索。全文索引在MySQL 中是一个FULLTEXT类型索引，但仅能用于MyISAM 类型的表。对于一个大的数据库，将数据装载到一个没有FULLTEXT索引的表中，然后再使用ALTER TABLE或CREATE INDEX创建索引，将是非常快的。但如果将数据装载到一个已经有FULLTEXT索引的表中，执行过程将会非常慢。<br />
<br />
　　<strong>8、优化的查询语句</strong><br />
<br />
　　绝大多数情况下，使用索引可以提高查询的速度，但如果SQL语句使用不恰当的话，索引将无法发挥它应有的作用。下面是应该注意的几个方面。首先，最好是在相同类型的字段间进行比较的操作。在MySQL 3.23版之前，这甚至是一个必须的条件。例如不能将一个建有索引的INT字段和BIGINT字段进行比较；但是作为特殊的情况，在CHAR类型的字段和VARCHAR类型字段的字段大小相同的时候，可以将它们进行比较。其次，在建有索引的字段上尽量不要使用函数进行操作。<br />
<br />
　　例如，在一个DATE类型的字段上使用YEAE()函数时，将会使索引不能发挥应有的作用。所以，下面的两个查询虽然返回的结果一样，但后者要比前者快得多。</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">SELECT </span><span style="color: #000000">*</span><span style="color: #000000"> FROM order WHERE YEAR(OrderDate)</span><span style="color: #000000">&lt;</span><span style="color: #000000">2001</span><span style="color: #000000">;<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />SELECT </span><span style="color: #000000">*</span><span style="color: #000000"> FROM order WHERE OrderDate</span><span style="color: #000000">&lt;</span><span style="color: #000000">"</span><span style="color: #000000">2001-01-01</span><span style="color: #000000">"</span><span style="color: #000000">;</span></div>
</div>
<p>同样的情形也会发生在对数值型字段进行计算的时候：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">SELECT </span><span style="color: #000000">*</span><span style="color: #000000"> FROM inventory WHERE Amount</span><span style="color: #000000">/</span><span style="color: #000000">7</span><span style="color: #000000">&lt;</span><span style="color: #000000">24</span><span style="color: #000000">;<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />SELECT </span><span style="color: #000000">*</span><span style="color: #000000"> FROM inventory WHERE Amount</span><span style="color: #000000">&lt;</span><span style="color: #000000">24</span><span style="color: #000000">*</span><span style="color: #000000">7</span><span style="color: #000000">; <br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
</div>
<p>上面的两个查询也是返回相同的结果，但后面的查询将比前面的一个快很多。第三，在搜索字符型字段时，我们有时会使用 LIKE 关键字和通配符，这种做法虽然简单，但却也是以牺牲系统性能为代价的。例如下面的查询将会比较表中的每一条记录。</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">SELECT </span><span style="color: #000000">*</span><span style="color: #000000"> FROM books<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />WHERE name like </span><span style="color: #000000">"</span><span style="color: #000000">MySQL%</span><span style="color: #000000">"</span></div>
</div>
<p>但是如果换用下面的查询，返回的结果一样，但速度就要快上很多：..</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">SELECT </span><span style="color: #000000">*</span><span style="color: #000000"> FROM books<br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" />WHERE name</span><span style="color: #000000">&gt;=</span><span style="color: #000000">"</span><span style="color: #000000">MySQL</span><span style="color: #000000">"</span><span style="color: #000000">and name</span><span style="color: #000000">&lt;</span><span style="color: #000000">"</span><span style="color: #000000">MySQM</span><span style="color: #000000">"</span><span style="color: #000000"> <br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
</div>
<p>最后，应该注意避免在查询中让MySQL进行自动类型转换，因为转换过程也会使索引变得不起作用。</p>
<img src ="http://www.blogjava.net/void241/aggbug/216002.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/void241/" target="_blank">void</a> 2008-07-19 12:16 <a href="http://www.blogjava.net/void241/archive/2008/07/19/216002.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MYSQL my.ini的1000人在线配置</title><link>http://www.blogjava.net/void241/archive/2008/07/19/215991.html</link><dc:creator>void</dc:creator><author>void</author><pubDate>Sat, 19 Jul 2008 04:05:00 GMT</pubDate><guid>http://www.blogjava.net/void241/archive/2008/07/19/215991.html</guid><wfw:comment>http://www.blogjava.net/void241/comments/215991.html</wfw:comment><comments>http://www.blogjava.net/void241/archive/2008/07/19/215991.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/void241/comments/commentRss/215991.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/void241/services/trackbacks/215991.html</trackback:ping><description><![CDATA[MYSQL my.ini的1000人在线配置 <br />
#This File was made using the WinMySQLAdmin 1.4 Tool <br />
#2004-2-23 16:28:14 <br />
#Uncomment or Add only the keys that you know how works. <br />
#Read the MySQL Manual for instructions <br />
[mysqld] <br />
basedir=D:/mysql <br />
#bind-address=210.5.*.* <br />
datadir=D:/mysql/data <br />
#language=D:/mysql/share/your language directory <br />
#slow query log#= <br />
#tmpdir#= <br />
#port=3306 <br />
set-variable = max_connections=1500 <br />
skip-locking <br />
#skip-networking <br />
set-variable = key_buffer=384M <br />
set-variable = max_allowed_packet=1M <br />
set-variable = table_cache=512 <br />
set-variable = sort_buffer=2M <br />
set-variable = record_buffer=2M <br />
set-variable = thread_cache=8 <br />
# Try number of CPU's*2 for thread_concurrency <br />
set-variable = thread_concurrency=8 <br />
set-variable = myisam_sort_buffer_size=64M <br />
#set-variable = connect_timeout=5 <br />
#set-variable = wait_timeout=5 <br />
server-id = 1 <br />
[isamchk] <br />
set-variable = key_buffer=128M <br />
set-variable = sort_buffer=128M <br />
set-variable = read_buffer=2M <br />
set-variable = write_buffer=2M <br />
[myisamchk] <br />
set-variable = key_buffer=128M <br />
set-variable = sort_buffer=128M <br />
set-variable = read_buffer=2M <br />
set-variable = write_buffer=2M <br />
[WinMySQLadmin] <br />
Server=D:/mysql/bin/mysqld-nt.exe<br />
<img src ="http://www.blogjava.net/void241/aggbug/215991.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/void241/" target="_blank">void</a> 2008-07-19 12:05 <a href="http://www.blogjava.net/void241/archive/2008/07/19/215991.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>