﻿<?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-Ginew.Z 的博客-随笔分类-MySQL</title><link>http://www.blogjava.net/ginew/category/9096.html</link><description>一切，为了让生活更简单、更自然</description><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 06:26:36 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 06:26:36 GMT</pubDate><ttl>60</ttl><item><title>我认为最好的MYSQL备份方式</title><link>http://www.blogjava.net/ginew/archive/2006/04/11/40439.html</link><dc:creator>无风之雨</dc:creator><author>无风之雨</author><pubDate>Tue, 11 Apr 2006 04:47:00 GMT</pubDate><guid>http://www.blogjava.net/ginew/archive/2006/04/11/40439.html</guid><wfw:comment>http://www.blogjava.net/ginew/comments/40439.html</wfw:comment><comments>http://www.blogjava.net/ginew/archive/2006/04/11/40439.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ginew/comments/commentRss/40439.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ginew/services/trackbacks/40439.html</trackback:ping><description><![CDATA[    要备份MYSQL，很多人用mysqldump，其实这种方式，导出的文件是最大的，导入的时间是最久的。命令是方便的，但真正发生错误的时候，恢复效率很低。<br />    我主张，另外找一台比较空闲的机器，来做数据库的备份。这台机器作以下用途：<br /><br />   它是主数据库带的slave数据库群里面的一台，每天凌晨定时启动同步数据，等追上bin-log并全部执行后，停止同步，并用select * into outfile将数据全部导出成文件，并且在每周的某一天，清除掉主数据库上已经同步好的bin-log，以确保硬盘空间不被log占满。<br /><br />   为此，我写了3个脚本，分别执行1、启动mysql，追log，然后停止slave；2、导出全部数据库全部文件到文件；3、删除主数据库的log<br /><br />---------------------------------------------------------------------------------------<br />#!/bin/bash<br />#readMasterMysql.sh<br />CHECK_MYSQL=0<br />/home/mysql/bin/mysqld_safe &amp;<br />until [ "$CHECK_MYSQL" = "1" ]<br />do<br />  sleep 10<br />  CHECK_MYSQL=`/home/mysql/bin/mysql -uroot -e"show slave status"|awk '{if($14==$21)print "1"}'|tail -n1`<br />done<br />/home/mysql/bin/mysql -uroot -e"slave stop"<br />/home/script/backupMysql.sh<br />/home/mysql/bin/mysqladmin shutdown<br />WEEK=`date "+%w"`<br />if [ $WEEK = "5" ]<br />then<br />    /home/script/purgeLog.sh<br />fi<br /><br />------------------------------------------------------------------------------<br />#!/bin/bash<br />#purgeLog.sh<br />LOG_FILE=/home/mysql/data/master.info<br />DB_SERVER=`sed -n '4p' $LOG_FILE`<br />DB_USER=`sed -n '5p' $LOG_FILE`<br />DB_PASS=`sed -n '6p' $LOG_FILE`<br />DB_LOGFILE=`sed -n '2p' $LOG_FILE`<br />/home/mysql/bin/mysql -h$DB_SERVER -u$DB_USER -p"$DB_PASS" -e"purge master logs to '$DB_LOGFILE'"<br /><br />------------------------------------------------------------------------------<br />#!/bin/bash<br />#backupMysql.sh<br />database=$1<br />table=$2<br />MYSQL_CLIENT="/home/mysql/bin/mysql -uroot --default-character-set=gbk"<br />MYSQL_DUMP="/home/mysql/bin/mysqldump -d -uroot --default-character-set=gbk"<br />OUTPUT_PATH=/date/backup<br />for databases in `$MYSQL_CLIENT -e "show databases"|grep -v Database`<br />do<br />if [ "$#" = "0" -o "$database" = "$databases" ] ; then<br />        mkdir -p -m777 $OUTPUT_PATH/$databases/<br />        $MYSQL_DUMP $databases &gt; $OUTPUT_PATH/$databases/$databases.sql<br />        for tables in `$MYSQL_CLIENT -e "show tables" $databases|grep -v Tables_in_`<br />        do<br />        if [ "$#" = "0" -o "$#" = "1" -o "$table" = "$tables" ] ; then<br />                mv -f $OUTPUT_PATH/$databases/$tables $OUTPUT_PATH/$databases/$tables.old<br />                $MYSQL_CLIENT -e "select * into outfile '$OUTPUT_PATH/$databases/$tables' from $tables" $databases<br />        fi<br />        done<br />fi<br />done<img src ="http://www.blogjava.net/ginew/aggbug/40439.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ginew/" target="_blank">无风之雨</a> 2006-04-11 12:47 <a href="http://www.blogjava.net/ginew/archive/2006/04/11/40439.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle到mysql的迁移，函数部分</title><link>http://www.blogjava.net/ginew/archive/2006/04/11/40429.html</link><dc:creator>无风之雨</dc:creator><author>无风之雨</author><pubDate>Tue, 11 Apr 2006 04:16:00 GMT</pubDate><guid>http://www.blogjava.net/ginew/archive/2006/04/11/40429.html</guid><wfw:comment>http://www.blogjava.net/ginew/comments/40429.html</wfw:comment><comments>http://www.blogjava.net/ginew/archive/2006/04/11/40429.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ginew/comments/commentRss/40429.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ginew/services/trackbacks/40429.html</trackback:ping><description><![CDATA[
		<p>to_date(?, 'YYYY-MM-DD HH24:MI:SS')"<br />STR_TO_DATE('2003-15-10 00:00:00','%Y-%m-%d %H:%i:%s');     //格式不对，会返回NULL</p>
		<p>to_char(create_time,'yyyy-MM-dd')<br />DATE_FORMAT(create_time,'%Y-%m-%d')</p>
		<p>sysdate<br />now()或者CURRENT_TIMESTAMP //'1997-12-15 23:50:26',建表的时候，timestamp类型可以指定default CURRENT_TIMESTAMP</p>
		<p>sysdate - 7   //7天前<br />now()-INTERVAL 7 DAY   </p>
		<p>select * from (select .... where rownum&lt;end) where rownum&gt;start<br />limit [start,] length</p>
		<p>substr(productInfor,1,20)<br />SUBSTRING('Quadratically',5,6)     //SUBSTRING(str,pos,len)</p>
		<p>instr(str,substr,pos,index)<br />instr(str,substr) 或者 locate(substr,str,pos)<br />// 没有相对应的语法，但一般情况，这个是和substr结合起来用的。<br />//如果是str="2005-10-01"取中间的10这样的需要，oracle是substr(str,instr(str,'-',1,1)+1,instr(str,'-',1,2)-instr(str,'-',1,1)-1)<br />那在mysql里面，可以试试这样SUBSTRING_INDEX(SUBSTRING_INDEX(str,'-',2),'-',-1),意思就是取第二个-之前的str后（2005-10），再取倒数第一个-之后的内容</p>
		<p>oracle的nvl（ss,dd）函数在mysql中怎么实现？ <br />答：ifnull(ss,dd)</p>
<img src ="http://www.blogjava.net/ginew/aggbug/40429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ginew/" target="_blank">无风之雨</a> 2006-04-11 12:16 <a href="http://www.blogjava.net/ginew/archive/2006/04/11/40429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Mysql到oracle程序迁移的注意事项</title><link>http://www.blogjava.net/ginew/archive/2006/04/11/40428.html</link><dc:creator>无风之雨</dc:creator><author>无风之雨</author><pubDate>Tue, 11 Apr 2006 04:15:00 GMT</pubDate><guid>http://www.blogjava.net/ginew/archive/2006/04/11/40428.html</guid><wfw:comment>http://www.blogjava.net/ginew/comments/40428.html</wfw:comment><comments>http://www.blogjava.net/ginew/archive/2006/04/11/40428.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ginew/comments/commentRss/40428.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ginew/services/trackbacks/40428.html</trackback:ping><description><![CDATA[
		<p>Mysql到oracle程序迁移的注意事项(摘抄)<br />有很多应用项目, 刚起步的时候用MYSQL数据库基本上能实现各种功能需求，随着应用用户的增多， <br />数据量的增加，MYSQL渐渐地出现不堪重负的情况：连接很慢甚至宕机，于是就有把数据从MYSQL迁到 <br />ORACLE的需求，应用程序也要相应做一些修改。本人总结出以下几点注意事项，希望对大家有所帮助。 </p>
		<p>1． 自动增长的数据类型处理 <br />MYSQL有自动增长的数据类型，插入记录时不用操作此字段，会自动获得数据值。 <br />ORACLE没有自动增长的数据类型，需要建立一个自动增长的序列号，插入记录时要把序列号的下一个 <br />值赋于此字段。 </p>
		<p>CREATE SEQUENCE 序列号的名称 (最好是表名+序列号标记) INCREMENT BY 1 START WITH 1 <br />MAXVALUE 99999 CYCLE NOCACHE; <br />其中最大的值按字段的长度来定, 如果定义的自动增长的序列号 NUMBER(6) , 最大值为999999 <br />INSERT 语句插入这个字段值为: 序列号的名称.NEXTVAL </p>
		<p>2. 单引号的处理 <br />MYSQL里可以用双引号包起字符串，ORACLE里只可以用单引号包起字符串。在插入和修改字符串 <br />前必须做单引号的替换：把所有出现的一个单引号替换成两个单引号。 </p>
		<p>3. 翻页的SQL语句的处理 <br />MYSQL处理翻页的SQL语句比较简单，用LIMIT 开始位置, 记录个数；PHP里还可以用SEEK定位到结果 <br />集的位置。 <br />ORACLE处理翻页的SQL语句就比较繁琐了。每个结果集只有一个ROWNUM字段标明它的位置, 并且只能 <br />用ROWNUM&lt;100, 不能用ROWNUM&gt;80。 <br />以下是经过分析后较好的两种ORACLE翻页SQL语句( ID是唯一关键字的字段名 )： <br />语句一： <br />SELECT ID, [FIELD_NAME,...] FROM TABLE_NAME WHERE ID IN ( SELECT ID FROM (SELECT <br />ROWNUM AS NUMROW, ID FROM TABLE_NAME WHERE 条件1 ORDER BY 条件2) WHERE NUMROW &gt; 80 AND <br />NUMROW &lt; 100 ) ORDER BY 条件3; </p>
		<p>语句二： <br />SELECT * FROM (( SELECT ROWNUM AS NUMROW, c.* from (select [FIELD_NAME,...] FROM <br />TABLE_NAME WHERE 条件1 ORDER BY 条件2) c) WHERE NUMROW &gt; 80 AND NUMROW &lt; 100 ) ORDER BY 条件3; </p>
		<p>4． 长字符串的处理 <br />长字符串的处理ORACLE也有它特殊的地方。INSERT和UPDATE时最大可操作的字符串长度小于等于 <br />4000个单字节, 如果要插入更长的字符串, 请考虑字段用CLOB类型，方法借用ORACLE里自带的DBMS_LOB程序 <br />包。插入修改记录前一定要做进行非空和长度判断，不能为空的字段值和超出长度字段值都应该提出警告, <br />返回上次操作。 </p>
		<p>5. 日期字段的处理 <br />MYSQL日期字段分DATE和TIME两种，ORACLE日期字段只有DATE，包含年月日时分秒信息，用当前数据库 <br />的系统时间为SYSDATE, 精确到秒，或者用字符串转换成日期型函数TO_DATE(‘2001-08-01’,’YYYY-MM-DD’) <br />年-月-日 24小时:分钟:秒 的格式YYYY-MM-DD HH24:MI:SS TO_DATE()还有很多种日期格式, 可以参看 <br />ORACLE DOC. <br />日期型字段转换成字符串函数TO_CHAR(‘2001-08-01’,’YYYY-MM-DD HH24:MI:SS’) </p>
		<p>日期字段的数学运算公式有很大的不同。 <br />MYSQL找到离当前时间7天用 <br />DATE_FIELD_NAME &gt; SUBDATE（（NOW（），INTERVAL 7 DAY） <br />ORACLE找到离当前时间7天用 <br />DATE_FIELD_NAME &gt;SYSDATE - 7; </p>
		<p>6. 空字符的处理 <br />MYSQL的非空字段也有空的内容，ORACLE里定义了非空字段就不容许有空的内容。 <br />按MYSQL的NOT NULL来定义ORACLE表结构, 导数据的时候会产生错误。因此导数据时要对空字符进行判 <br />断，如果为NULL或空字符，需要把它改成一个空格的字符串。 </p>
		<p>7. 字符串的模糊比较 <br />MYSQL里用 字段名 like '%字符串%' <br />ORACLE里也可以用 字段名 like '%字符串%' 但这种方法不能使用索引, 速度不快 <br />用字符串比较函数 instr(字段名,'字符串')&gt;0 会得到更精确的查找结果 </p>
		<p>8. 程序和函数里，操作数据库的工作完成后请注意结果集和指针的释放。 </p>
		<p>
				<br />有兴趣可以看MYSQL管理员指南 </p>
<img src ="http://www.blogjava.net/ginew/aggbug/40428.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ginew/" target="_blank">无风之雨</a> 2006-04-11 12:15 <a href="http://www.blogjava.net/ginew/archive/2006/04/11/40428.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MYSQL特殊函数</title><link>http://www.blogjava.net/ginew/archive/2006/04/11/40426.html</link><dc:creator>无风之雨</dc:creator><author>无风之雨</author><pubDate>Tue, 11 Apr 2006 04:13:00 GMT</pubDate><guid>http://www.blogjava.net/ginew/archive/2006/04/11/40426.html</guid><wfw:comment>http://www.blogjava.net/ginew/comments/40426.html</wfw:comment><comments>http://www.blogjava.net/ginew/archive/2006/04/11/40426.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ginew/comments/commentRss/40426.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ginew/services/trackbacks/40426.html</trackback:ping><description><![CDATA[
		<p>1、用mysql内置函数转换ip地址和数字<br />利用两个内置函数<br />inet_aton:将ip地址转换成数字型<br />inet_ntoa:将数字型转换成ip地址</p>
		<p>2、用Mysql内置函数来转化unix时间(秒值)和字符串时间<br />from_unixtime():1144728462 -&gt; "2006-04-11 12:07:42"<br />unix_timestamp():"2006-04-11 12:07:42" -&gt; 1144728462</p>
<img src ="http://www.blogjava.net/ginew/aggbug/40426.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ginew/" target="_blank">无风之雨</a> 2006-04-11 12:13 <a href="http://www.blogjava.net/ginew/archive/2006/04/11/40426.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MYSQL5.1的表分区功能</title><link>http://www.blogjava.net/ginew/archive/2006/04/11/40414.html</link><dc:creator>无风之雨</dc:creator><author>无风之雨</author><pubDate>Tue, 11 Apr 2006 03:47:00 GMT</pubDate><guid>http://www.blogjava.net/ginew/archive/2006/04/11/40414.html</guid><wfw:comment>http://www.blogjava.net/ginew/comments/40414.html</wfw:comment><comments>http://www.blogjava.net/ginew/archive/2006/04/11/40414.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ginew/comments/commentRss/40414.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ginew/services/trackbacks/40414.html</trackback:ping><description><![CDATA[
		<div class="node ">
				<div class="content">
						<p>Improving Database Performance with Partitioning</p>
						<p>A few years ago, I wrote an article entitled "The Foundation of Excellent Performance" (still available at http://www.tdan.com/i016fe03.htm) where I argued against the notion that SQL code was the number one contributor to performance in a database-driven system. Instead, I stated in the article that I firmly believed how good physical database design was far and away the leading component of superior database performance. In addition, I showed that Oracle's own research illustrated how poor design was the main culprit behind database downtime (planned or unplanned). In the years since then, I've not changed my stance and still think that any DBA who wants a high-performance database has got to invest in intelligent and savvy physical design to produce the kind of response times that make end users smile instead of scream.</p>
						<p>One of the reasons I'm very excited about the release of MySQL 5.1 is that it contains a potent new weapon for designing supercharged databases that any MySQL DBA should quickly learn how to use and exploit. By smartly using the new 5.1 partitioning feature, a DBA can oftentimes dramatically improve the performance of most any VLDB or data warehouse they happen to be in charge of.<br />What is Partitioning?</p>
						<p>Partitioning is a physical database design technique that many data modelers and DBAs are quite familiar with. Although partitioning can be used to accomplish a number of various objectives, the main goal is to reduce the amount of data read for particular SQL operations so that overall response time is reduced.</p>
						<p>There are two major forms of partitioning:</p>
						<p>1. Horizontal Partitioning - this form of partitioning segments table rows so that distinct groups of physical row-based datasets are formed that can be addressed individually (one partition) or collectively (one-to-all partitions). All columns defined to a table are found in each set of partitions so no actual table attributes are missing. An example of horizontal partitioning might be a table that contains ten years worth of historical invoice data being partitioned into ten distinct partitions, where each partition contains a single year's worth of data.<br />2. Vertical Partitioning - this partitioning scheme is traditionally used to reduce the width of a target table by splitting a table vertically so that only certain columns are included in a particular dataset, with each partition including all rows. An example of vertical partitioning might be a table that contains a number of very wide text or BLOB columns that aren't addressed often being broken into two tables that has the most referenced columns in one table and the seldom-referenced text or BLOB data in another.</p>
						<p>Before database vendors began building partitioning (mainly horizontal) into their engines, DBAs and data modelers had to physically design separate table structures to hold the desired partitions, which either held redundant data (separate tables with data that were based off a live parent table) or were linked together to form one logical parent object (usually via a view). This practice has since been made obsolete for the most part for horizontal partitioning, although it is sometimes still done for vertical partitioning.<br />Partitioning in MySQL 5.1</p>
						<p>One of the great new features in MySQL 5.1 is support for horizontal partitioning. The really good news about MySQL and the new 5.1 partitioning feature is all the major forms of partitioning are supported:</p>
						<p>1. Range - this partitioning mode allows a DBA to specify various ranges for which data is assigned. For example, a DBA may create a partitioned table that is segmented by three partitions that contain data for the 1980's, 1990's, and everything beyond and including the year 2000.<br />2. Hash - this partitioning mode allows a DBA to separate data based on a computed hash key that is defined on one or more table columns, with the end goal being an equal distribution of values among partitions. For example, a DBA may create a partitioned table that has ten partitions that are based on the table's primary key.<br />3. Key - a special form of Hash where MySQL guarantees even distribution of data through a system-generated hash key.<br />4. List - this partitioning mode allows a DBA to segment data based on a pre-defined list of values that the DBA specifies. For example, a DBA may create a partitioned table that contains three partitions based on the years 2004, 2005, and 2006.<br />5. Composite - this final partitioning mode allows a DBA to perform sub-partitioning where a table is initially partitioned by, for example range partitioning, but then each partition is segmented even further by another method (for example, hash).</p>
						<p>There are a number of benefits that come with partitioning, but the two main advantages are:</p>
						<p>Increased performance - during scan operations, the MySQL optimizer knows what partitions contain the data that will satisfy a particular query and will access only those necessary partitions during query execution. For example, a million row table may be broken up into ten different partitions in range style so that each partition contains 100,000 rows. If a query is issued that only needs data from one of the partitions, and a table scan operation is necessary, only 100,000 rows will be accessed instead of a million. Obviously, it is much quicker for MySQL to sample 100,000 rows than one million so the query will complete much sooner. The same benefit is derived should index access be possible as local partitioned indexes are created for partitioned tables. Finally, it is possible to stripe a partitioned table across different physical drives by specifying different file system/directory paths for specific partitions. This allows physical I/O contention to be reduced when multiple partitions are accessed at the same time.<br />Simplified data management - partitioning allows a DBA to have more control over how data is managed inside of the database. By intelligently creating partitions, a DBA can simplify how certain data operations are performed. For example, a DBA can drop specific partitions in a partitioned table while the remaining partitions remain intact (as opposed to crafting a fragmentation-producing mass delete operation for the whole table). Further, partitions are automatically maintained by MySQL so the DBA doesn't have to manually separate and maintain a horizontal partitioning scheme for a table. For example, a DBA can create a history table that holds data for customers that are partitioned across various year ranges, and have those partitioned automatically enforced by the database server with no DBA intervention being necessary.</p>
						<p>From a design-for-performance standpoint, we're mainly interested in point one above. By smartly using partitioning and matching the design to properly coded queries, a dramatic performance impact can be realized. Let's take a quick test drive of partitioning in MySQL 5.1 to see this in action. Note that all tests below were done on a Dell Optiplex box with a Pentium 4 3.00GHz processor, 1GB of RAM, running Fedora Core 4 and MySQL 5.1.6 alpha.<br />Partitioning in Action</p>
						<p>To see the positive benefit partitioning can have on a database, let's create identical MyISAM tables that contain date sensitive information, but let's partition one and leave the other a standard heap table. For our partitioned table, we'll partition based on range and use a function that segments the data based on year:</p>
						<p>mysql&gt; CREATE TABLE part_tab<br />-&gt; ( c1 int default NULL,<br />-&gt; c2 varchar(30) default NULL,<br />-&gt; c3 date default NULL<br />-&gt;<br />-&gt; ) engine=myisam<br />-&gt; PARTITION BY RANGE (year(c3)) (PARTITION p0 VALUES LESS THAN (1995),<br />-&gt; PARTITION p1 VALUES LESS THAN (1996) , PARTITION p2 VALUES LESS THAN (1997) ,<br />-&gt; PARTITION p3 VALUES LESS THAN (1998) , PARTITION p4 VALUES LESS THAN (1999) ,<br />-&gt; PARTITION p5 VALUES LESS THAN (2000) , PARTITION p6 VALUES LESS THAN (2001) ,<br />-&gt; PARTITION p7 VALUES LESS THAN (2002) , PARTITION p8 VALUES LESS THAN (2003) ,<br />-&gt; PARTITION p9 VALUES LESS THAN (2004) , PARTITION p10 VALUES LESS THAN (2010),<br />-&gt; PARTITION p11 VALUES LESS THAN MAXVALUE );<br />Query OK, 0 rows affected (0.00 sec)</p>
						<p>Notice that we designed partitions for a particular year and finished with one catch-all partition to get anything that doesn't fall into any of the specific date partitions. Now let's create a mirror MyISAM table that's not partitioned:</p>
						<p>mysql&gt; create table no_part_tab<br />-&gt; (c1 int(11) default NULL,<br />-&gt; c2 varchar(30) default NULL,<br />-&gt; c3 date default NULL) engine=myisam;<br />Query OK, 0 rows affected (0.02 sec)</p>
						<p>Now let's create a procedure (thanks to Peter Gulutzan for the code) that will fill our partitioned table with 8 million rows that distributes data fairly evenly across the various partitions. Once filled, we'll then insert the same data into our non-partitioned MyISAM clone table:</p>
						<p>mysql&gt; delimiter //<br />mysql&gt; CREATE PROCEDURE load_part_tab()<br />-&gt; begin<br />-&gt; declare v int default 0;<br />-&gt; while v &lt; 8000000<br />-&gt; do<br />-&gt; insert into part_tab<br />-&gt; values (v,'testing partitions',adddate('1995-01-01',(rand(v)*36520) mod 3652));<br />-&gt; set v = v + 1;<br />-&gt; end while;<br />-&gt; end<br />-&gt; //<br />Query OK, 0 rows affected (0.00 sec)<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>With our tables now ready, let's issue a simple date range query on both tables - the non-partitioned table first and then the partitioned table - followed by EXPLAIN's, and see what MySQL does:</p>
						<p>mysql&gt; select count(*) from no_part_tab where<br />-&gt; c3 &gt; date '1995-01-01' and c3 &lt; date '1995-12-31';<br />+----------+<br />| count(*) |<br />+----------+<br />| 795181 |<br />+----------+<br />1 row in set (38.30 sec)</p>
						<p>mysql&gt; select count(*) from part_tab where<br />-&gt; c3 &gt; date '1995-01-01' and c3 &lt; date '1995-12-31';<br />+----------+<br />| count(*) |<br />+----------+<br />| 795181 |<br />+----------+<br />1 row in set (3.88 sec)</p>
						<p>mysql&gt; explain select count(*) from no_part_tab where<br />-&gt; c3 &gt; date '1995-01-01' and c3 &lt; date '1995-12-31'\G<br />*************************** 1. row ***************************<br />id: 1<br />select_type: SIMPLE<br />table: no_part_tab<br />type: ALL<br />possible_keys: NULL<br />key: NULL<br />key_len: NULL<br />ref: NULL<br />rows: 8000000<br />Extra: Using where<br />1 row in set (0.00 sec)</p>
						<p>mysql&gt; explain partitions select count(*) from part_tab where<br />-&gt; c3 &gt; date '1995-01-01' and c3 &lt; date '1995-12-31'\G<br />*************************** 1. row ***************************<br />id: 1<br />select_type: SIMPLE<br />table: part_tab<br />partitions: p1<br />type: ALL<br />possible_keys: NULL<br />key: NULL<br />key_len: NULL<br />ref: NULL<br />rows: 798458<br />Extra: Using where<br />1 row in set (0.00 sec)</p>
						<p>The power of proper partition and query design can easily be seen as the partitioned table access delivers a whopping 90% response time reduction over the non-partitioned table. The EXPLAIN plans showcase why this is (notice the new EXPLAIN syntax for partitioned objects) as only the first partition in the partitioned table is accessed with all others being skipped.</p>
						<p>As a MySQL DBA, it's easy to get excited about the potential benefits that partitioning can provide, but you always want to make sure that the tool you use for database design matches the requirements and scenario of your particular application. Partitioning is best suited for VLDB's that contain a lot of query activity that targets specific portions/ranges of one or more database tables. Of course, other situations lend themselves to partitioning as well (e.g. data archiving, etc.)<br />A Quick Side Note on Vertical Partitioning</p>
						<p>Although MySQL 5.1 automates horizontal partitioning, don't lose sight of vertical partitioning schemes when designing your databases. Although you have to do vertical partitioning manually, you can benefit from the practice in certain circumstances. For example, let's say you didn't normally need to reference or use the VARCHAR column defined in our previously shown partitioned table. Would the elimination of this column help query speed? Let's find out:</p>
						<p>mysql&gt; desc part_tab;<br />+-------+-------------+------+-----+---------+-------+<br />| Field | Type | Null | Key | Default | Extra |<br />+-------+-------------+------+-----+---------+-------+<br />| c1 | int(11) | YES | | NULL | |<br />| c2 | varchar(30) | YES | | NULL | |<br />| c3 | date | YES | | NULL | |<br />+-------+-------------+------+-----+---------+-------+<br />3 rows in set (0.03 sec)</p>
						<p>mysql&gt; alter table part_tab drop column c2;<br />Query OK, 8000000 rows affected (42.20 sec)<br />Records: 8000000 Duplicates: 0 Warnings: 0</p>
						<p>mysql&gt; desc part_tab;<br />+-------+---------+------+-----+---------+-------+<br />| Field | Type | Null | Key | Default | Extra |<br />+-------+---------+------+-----+---------+-------+<br />| c1 | int(11) | YES | | NULL | |<br />| c3 | date | YES | | NULL | |<br />+-------+---------+------+-----+---------+-------+<br />2 rows in set (0.00 sec)</p>
						<p>mysql&gt; select count(*) from part_tab where<br />-&gt; c3 &gt; date '1995-01-01' and c3 &lt; date '1995-12-31';<br />+----------+<br />| count(*) |<br />+----------+<br />| 795181 |<br />+----------+<br />1 row in set (0.34 sec)</p>
						<p>By removing the VARCHAR column from the design, you actually get another 90+% reduction in query response time. Beyond partitioning, this speaks to the effect wide tables can have on queries and why you should always ensure that all columns defined to a table are actually needed.<br />Wrap Up</p>
						<p>A short article like this can't possibly cover all the benefits and mechanics of MySQL 5.1's partitioning, but a few notes of interest include:</p>
						<p>* All storage engines support partitioning (MyISAM, Archive, InnoDB, etc.)<br />* Indexing support for partitioned tables include local indexes, which mirror each partition in a one-to-one scheme. In other words, if a partitioned table has ten partitions, then a local index for that table would also contain ten partitions.<br />* Metadata regarding partitioned tables can be found in the INFORMATION_SCHEMA database, with a new PARTITIONS table being available.<br />* All SHOW commands support the return of partitioned table and index metadata.<br />* Maintenance functions and a number of other operations can be performed on partitions (rather than acting on a full table), including:<br />o ADD PARTITION<br />o DROP PARTITION<br />o COALESCE PARTITION<br />o REORGANIZE PARTITION<br />o ANALYZE PARTITION<br />o CHECK PARTITION<br />o OPTIMIZE PARTITION<br />o REBUILD PARTITION<br />o REPAIR PARTITION</p>
						<p>From a performance standpoint, the main take-away is that MySQL 5.1 partitioning is a powerful new tool that can be used in many physical database designs to dramatically improve performance and ease DBA management burdens. For more information on MySQL partitioning, you can visit out the online reference manual at http://dev.mysql.com/doc/refman/5.1/en/partitioning.html and visit the MySQL forums as there is a forum section devoted to partitioning, which can be referenced at http://forums.mysql.com/list.php?106.</p>
						<p>Download a copy of MySQL 5.1 (which is now is beta) today and give partitioning a try. I think you will be pleased with all the new possibilities partitioning provides when it comes to creating a top-notch physical database design, which is the number one contributor to overall database performance.</p>
				</div>
		</div>
<img src ="http://www.blogjava.net/ginew/aggbug/40414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ginew/" target="_blank">无风之雨</a> 2006-04-11 11:47 <a href="http://www.blogjava.net/ginew/archive/2006/04/11/40414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从头到尾优化MYSQL</title><link>http://www.blogjava.net/ginew/archive/2006/03/30/38299.html</link><dc:creator>无风之雨</dc:creator><author>无风之雨</author><pubDate>Thu, 30 Mar 2006 09:49:00 GMT</pubDate><guid>http://www.blogjava.net/ginew/archive/2006/03/30/38299.html</guid><wfw:comment>http://www.blogjava.net/ginew/comments/38299.html</wfw:comment><comments>http://www.blogjava.net/ginew/archive/2006/03/30/38299.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ginew/comments/commentRss/38299.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ginew/services/trackbacks/38299.html</trackback:ping><description><![CDATA[    MYSQL用了好多年了，一次次的优化，一次次的顶过崩溃的边缘，相信能有这样经历的人也不多。这里我写一点这么多年来优化MYSQL的经验。<br /><br />    让我们从头开始<br /><br />     什么机器比较适合跑MYSQL？原则就是IO操作一定要快，要少。在这个原则下，内存肯定是越大越好，硬盘肯定是越快越好。1快硬盘不够快，那就两块，做RAID0。<br />    什么操作系统比较适合跑MYSQL？我试过Linux,FreeBSD,Solaris。solaris是最差的，因为IO慢，的确比其他两个慢，所以我都不用它了。FBSD和linux哪个好？这个我倒是没认真比过，感觉上，fbsd的IO比linux快，所以我有一个5千万条记录的mysql跑在fbsd上，访问量很高的情况下，感觉还是很快。最近的项目都统一到Linux下了，感觉mysql在linux下跑，也不错。看过不少评测，都说mysql在linux比fbsd快，因为我没有实际对比，只有各自的体会，所以也不多评论了。不过fbsd有一点要注意，它默认的数据段大小只有1G，你想开大缓存，就必须重新编译内核，不然会数据段错。<br />    MYSQL5.1都已经在测试了，我们应该用什么版本？如果你是新开发一个产品，建议用5.0，不过我没实际用过，不好说。我用的最多的是3.23.x和4.1.x。由于没有在相同的环境下测试，所以不敢说哪个版本性能最好。所以还是只推荐5.0或者4.1毕竟是现在MYSQL主推的，比较有保证。<br />    我最近用的最多的是4.1。现在我一般会下载for linux＋icc编译的二进制包，以前我一般下源文件自己编译，源代码编译的是否好，直接影响性能。关于编译mysql的选项，足够另外写一篇东西了。这里就不提了，有兴趣的看看BUILD目录下的东西。现在我常用的是编译好的二进制包，因为他的编译环境已经基本最优化，而且加上icc编译器的优化，性能还能有一点提升。<br />    接着就是my.cnf了。我一般在support-files目录下的my-innodb-heavy-4G.cnf文件的基础上来修改。对性能影响比较大的，有table_cache，sort_buffer_size，join_buffer_size，query_cache_size，key_buffer_size，read_buffer_size，innodb_additional_mem_pool_size，innodb_buffer_pool_size。用INNODB是肯定的。innodb_additional_mem_pool_size可以大一点，我一般设256M，可以减少不断增加缓存的操作，innodb_buffer_pool_size是初始化的缓存，我觉得2G有点太大了，我倾向于给操作系统本身留点缓存空间。我一般设到1.2G，他自己有需要，也会慢慢涨到2G。<img src ="http://www.blogjava.net/ginew/aggbug/38299.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ginew/" target="_blank">无风之雨</a> 2006-03-30 17:49 <a href="http://www.blogjava.net/ginew/archive/2006/03/30/38299.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于MYSQL的内存优化</title><link>http://www.blogjava.net/ginew/archive/2006/03/30/38286.html</link><dc:creator>无风之雨</dc:creator><author>无风之雨</author><pubDate>Thu, 30 Mar 2006 09:15:00 GMT</pubDate><guid>http://www.blogjava.net/ginew/archive/2006/03/30/38286.html</guid><wfw:comment>http://www.blogjava.net/ginew/comments/38286.html</wfw:comment><comments>http://www.blogjava.net/ginew/archive/2006/03/30/38286.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ginew/comments/commentRss/38286.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ginew/services/trackbacks/38286.html</trackback:ping><description><![CDATA[
		<p>    网站有3台MYSQL服务器，其中1台是主服务器，2台从服务器。主从之间用Replication实时同步。<br />    最近，随着网站流量的提高，3台服务器在繁忙时段都达到饱和。通过分析服务器状态，发现服务器都已经开始使用交换分区，此举无疑会提高服务器对IO的使用频率。<br /><br />    2台从服务器中，一台4G内存的服务器处理能力比另外一台2G内存的服务器强1倍，两台服务器的差别，在CPU上差别并不大，RAID1对IO性能也不会有很大提高。所以断定通过把2G内存升级到4G，可以让此机的处理能力大大提高。<br /><br />    昨天晚上，给2台2G内存的MYSQL加大了内存，到4G，现在MYSQL在最繁忙时段都已经能应付自如了。<br /><br />    我还特地申请了一台新机器来做从服务器，配置如下：双XEON3.0/4GRAM/2块146GSCSI做RAID0。估计此机的整体处理能力会非常好。<br /><br />    结论：实际验证了IO对于数据库系统性能的影响。在MYSQL本身已经无可优化的情况下，加大内存或者把磁盘做RAID0能得到1倍的以上的性能提升</p>
<img src ="http://www.blogjava.net/ginew/aggbug/38286.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ginew/" target="_blank">无风之雨</a> 2006-03-30 17:15 <a href="http://www.blogjava.net/ginew/archive/2006/03/30/38286.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>