<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>水草树 &#187; mysql</title>
	<atom:link href="http://mifunny.info/tag/mysql/feed" rel="self" type="application/rss+xml" />
	<link>http://mifunny.info</link>
	<description>走走停停看看，恍然大悟。</description>
	<lastBuildDate>Sat, 27 Aug 2011 18:25:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Query Cache &#8211; MySQL邯郸学步</title>
		<link>http://mifunny.info/query-cache-in-mysql-332.html</link>
		<comments>http://mifunny.info/query-cache-in-mysql-332.html#comments</comments>
		<pubDate>Tue, 23 Mar 2010 13:23:33 +0000</pubDate>
		<dc:creator>LD</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[MySQL优化]]></category>
		<category><![CDATA[QC]]></category>
		<category><![CDATA[Query Cache]]></category>

		<guid isPermaLink="false">http://mifunny.info/?p=332</guid>
		<description><![CDATA[在MySQL中有一个Query Cache, 作为类CMS这样的内容导向应用很有用. 开启也很方便, 在 my.conf 中加入 query_cache_type 和 query_cache_size 参数. query_cache_type 0 代表不使用缓冲; 1 代表使用缓冲; 2 代表根据需要使用. 开启QC后,对于频繁更新的表, 使用 SQL_NO_CACHE 屏蔽cache, 如: SELECT SQL_NO_CACHE * FROM test.test001 WHERE &#8230;. ; 如果QC类型为2, 在需要cache时, 使用 SQL_CACHE 打开缓存, 如: SELECT SQL_CACHE * FROM test.test001 WHERE &#8230; ; 网上摘录了一段说明: 1. 何时cache a) mysql query cache内容为 select 的结果集, cache [...]]]></description>
			<content:encoded><![CDATA[<p>在MySQL中有一个Query Cache, 作为类CMS这样的内容导向应用很有用. 开启也很方便, 在 my.conf 中加入 query_cache_type 和 query_cache_size 参数.</p>
<p>query_cache_type 0 代表不使用缓冲; 1 代表使用缓冲; 2 代表根据需要使用.</p>
<p>开启QC后,对于频繁更新的表, 使用 SQL_NO_CACHE 屏蔽cache, 如: SELECT SQL_NO_CACHE * FROM test.test001 WHERE &#8230;. ;</p>
<p>如果QC类型为2, 在需要cache时, 使用 SQL_CACHE 打开缓存, 如: SELECT SQL_CACHE * FROM test.test001 WHERE &#8230; ;</p>
<p><span id="more-332"></span>网上摘录了一段说明:<br /> <br />
<strong>1. 何时cache</strong> </p>
<p>a) mysql query cache内容为 select 的结果集, cache 使用完整的 sql 字符串做 key, 并区分大小写，空格等。即两个sql必须完全一致才会导致cache命中。<br /> <br />
    b) prepared statement永远不会cache到结果，即使参数完全一样。据说在 5.1 之后会得到改善。<br /> <br />
    c) where条件中如包含了某些函数永远不会被cache, 比如current_date, now等。<br /> <br />
    d) date 之类的函数如果返回是以小时或天级别的，最好先算出来再传进去。<br />
select * from foo where date1=current_date &#8212; 不会被 cache<br />
select * from foo where date1=&#8217;2008-12-30&#8242; &#8212; 被cache, 正确的做法<br /> <br />
e) 太大的result set不会被cache (&lt; query_cache_limit)</p>
<p><strong>2. 何时invalidate</strong> </p>
<p>a) 一旦表数据进行任何一行的修改，基于该表相关cache立即全部失效。<br /> <br />
b) 为什么不做聪明一点判断修改的是否cache的内容？因为分析cache内容太复杂，服务器需要追求最大的性能。</p>
<p><strong>3. 性能</strong> </p>
<p>a) cache 未必所有场合总是会改善性能<br />
当有大量的查询和大量的修改时，cache机制可能会造成性能下降。因为每次修改会导致系统去做cache失效操作，造成不小开销。<br />
另外系统cache的访问由一个单一的全局锁来控制，这时候大量&gt;的查询将被阻塞，直至锁释放。所以不要简单认为设置cache必定会带来性能提升。<br />b) 大result set不会被cache的开销<br />
太大的result set不会被cache, 但mysql预先不知道result set的长度，所以只能等到reset set在cache添加到临界值 query_cache_limit 之后才会简单的把这个cache 丢弃。这并不是一个高效的操作。如果mysql status中Qcache_not_cached太大的话, 则可对潜在的大结果集的sql显式添加 SQL_NO_CACHE 的控制。<br />
query_cache_min_res_unit = (query_cache_size – Qcache_free_memory) / Qcache_queries_in_cache</p>
<p><strong>4. 内存池使用</strong> </p>
<p>mysql query cache 使用内存池技术，自己管理内存释放和分配，而不是通过操作系统。内存池使用的基本单位是变长的block, 一个result set的cache通过链表把这些block串起来。因为存放result set的时候并不知道这个resultset最终有多大。block最短长度为 query_cache_min_res_unit, resultset 的最后一个block会执行trim操作。
</p>
<p>还有一个比较全的: <a rel="external" href="http://www.surfchen.org/wiki/MySQL优化#Query_Cache">http://www.surfchen.org/wiki/MySQL优化#Query_Cache</a><br /><a rel="external" href="http://www.freelamp.com/1103001969/index_html"> MySQL Query Cache 效率的计算</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://mifunny.info/query-cache-in-mysql-332.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL转SQLite Shell脚本</title>
		<link>http://mifunny.info/convert-mysql-to-sqlite-script-330.html</link>
		<comments>http://mifunny.info/convert-mysql-to-sqlite-script-330.html#comments</comments>
		<pubDate>Mon, 01 Mar 2010 15:28:22 +0000</pubDate>
		<dc:creator>LD</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PDO]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sed]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://mifunny.info/?p=330</guid>
		<description><![CDATA[杭城焰火满天飞, 闲来无事, 给 WordPress 换上SQLite; SQLite 在单服务器10W并发以下是很有优势的, 据说可以达到mysql与postgresql的2~20倍(道听途说, 没验证)。 使用WP插件pdo for wordpress, 本来使用XML导入导出数据, 奈何文件太大, 超过php的内存限制,找了个MySQL转SQLite的教本, 很好用, 分享。 文件: mysql2sqlite.sh &#160;1 #!/bin/bash &#160;2 # MySQL 2 SQLite &#160;3 if [&#160;&#34;x$1&#34;&#160;==&#160;&#34;x&#34;&#160;];&#160;then &#160;4 &#160;&#160;&#160;&#160;echo&#160;&#34;Usage: $0&#160;&#60;dumpname&#62;&#34; &#160;5 &#160;&#160;&#160;&#160;exit &#160;6 fi &#160;7 &#160;8 cat $1&#160;&#124; &#160;9 grep&#160;-v&#160;&#8216;&#160;KEY &#34;&#8216;&#160;&#124; 10 grep&#160;-v&#160;&#8216;&#160;UNIQUE KEY &#34;&#8216;&#160;&#124; 11 grep&#160;-v&#160;&#8216;&#160;PRIMARY KEY &#8216;&#160;&#124; 12 sed&#160;&#8216;/^SET/d&#8216;&#160;&#124; 13 sed&#160;&#8216;s/ [...]]]></description>
			<content:encoded><![CDATA[<p>杭城焰火满天飞, 闲来无事, 给 WordPress 换上SQLite; SQLite 在单服务器10W并发以下是很有优势的, 据说可以达到mysql与postgresql的2~20倍(道听途说, 没验证)。 使用WP插件<a href="http://wordpress.org/extend/plugins/pdo-for-wordpress/" title="PDO (SQLite) For WordPress">pdo for wordpress</a>, 本来使用XML导入导出数据, 奈何文件太大, 超过php的内存限制,找了个MySQL转SQLite的教本, 很好用, 分享。</p>
<p><strong>文件: </strong> mysql2sqlite.sh<br />
<span id="more-330"></span> </p>
<blockquote style="background:#333333;color:#ffffff;font-style:normal;"><p>
<font color="#ffff00">&nbsp;1 </font><font color="#00ffff">#!/bin/bash</font><br /> <br />
<font color="#ffff00">&nbsp;2 </font><font color="#00ffff"># MySQL 2 SQLite</font><br /> <br />
<font color="#ffff00">&nbsp;3 </font><font color="#ffff00">if </font><font color="#ffff00">[</font>&nbsp;<font color="#ffff00">&quot;</font><font color="#ffff00">x</font><font color="#ff40ff">$1</font><font color="#ffff00">&quot;</font>&nbsp;<font color="#ffff00">==</font>&nbsp;<font color="#ffff00">&quot;x&quot;</font>&nbsp;<font color="#ffff00">]</font><font color="#ffff00">;</font>&nbsp;<font color="#ffff00">then</font><br /> <br />
<font color="#ffff00">&nbsp;4 </font>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">echo</font><font color="#ffff00">&nbsp;</font><font color="#ffff00">&quot;</font><font color="#ffff00">Usage: </font><font color="#ff40ff">$0</font><font color="#ffff00">&nbsp;&lt;dumpname&gt;</font><font color="#ffff00">&quot;</font><br /> <br />
<font color="#ffff00">&nbsp;5 </font>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">exit</font><br /> <br />
<font color="#ffff00">&nbsp;6 </font><font color="#ffff00">fi</font><br /> <br />
<font color="#ffff00">&nbsp;7 </font><br /> <br />
<font color="#ffff00">&nbsp;8 </font>cat <font color="#ff40ff">$1</font>&nbsp;|<br /> <br />
<font color="#ffff00">&nbsp;9 </font><font color="#ffff00">grep</font>&nbsp;<font color="#ff40ff">-v</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">&nbsp;KEY &quot;</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">10 </font><font color="#ffff00">grep</font>&nbsp;<font color="#ff40ff">-v</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">&nbsp;UNIQUE KEY &quot;</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">11 </font><font color="#ffff00">grep</font>&nbsp;<font color="#ff40ff">-v</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">&nbsp;PRIMARY KEY </font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">12 </font><font color="#ffff00">sed</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">/^SET/d</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">13 </font><font color="#ffff00">sed</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">s/ unsigned / /g</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">14 </font><font color="#ffff00">sed</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">s/ auto_increment/ primary key autoincrement/g</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">15 </font><font color="#ffff00">sed</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">s/ smallint([0-9]*) / integer /g</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">16 </font><font color="#ffff00">sed</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">s/ tinyint([0-9]*) / integer /g</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">17 </font><font color="#ffff00">sed</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">s/ int([0-9]*) / integer /g</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">18 </font><font color="#ffff00">sed</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">s/ character set [^ ]* / /g</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">19 </font><font color="#ffff00">sed</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">s/ enum([^)]*) / varchar(255) /g</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">20 </font><font color="#ffff00">sed</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">s/ on update [^,]*//g</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">21 </font><font color="#ffff00">sed</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">s/</font><font color="#ff40ff">\\</font><font color="#ffff00">r</font><font color="#ff40ff">\\</font><font color="#ffff00">n/</font><font color="#ff40ff">\\</font><font color="#ffff00">n/g</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">22 </font><font color="#ffff00">sed</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">s/</font><font color="#ff40ff">\\</font><font color="#ffff00">&quot;/&quot;/g</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">23 </font>perl <font color="#ff40ff">-e</font>&nbsp;<font color="#ffff00">&#8216;</font><font color="#ffff00">local $/;$_=&lt;&gt;;s/,\n</font><font color="#ff40ff">\)</font><font color="#ffff00">/\n</font><font color="#ff40ff">\)</font><font color="#ffff00">/gs;print &quot;begin;\n&quot;;print;print &quot;commit;\n&quot;</font><font color="#ffff00">&#8216;</font>&nbsp;|<br /> <br />
<font color="#ffff00">24 </font>perl <font color="#ff40ff">-pe</font>&nbsp;<font color="#ffff00">&#8216;</font><br /> <br />
<font color="#ffff00">25 </font><font color="#ffff00">if (/^(INSERT.+?)</font><font color="#ff40ff">\(</font><font color="#ffff00">/) {</font><br /> <br />
<font color="#ffff00">26 </font><font color="#ffff00">&nbsp;&nbsp;$a=$1;</font><br /> <br />
<font color="#ffff00">27 </font><font color="#ffff00">&nbsp;&nbsp;s/</font><font color="#ff40ff">\\</font><font color="#ffff00">&#8216;</font><font color="#ff40ff">\&#8217;</font><font color="#ffff00">&#8216;</font><font color="#ffff00">/</font><font color="#ffff00">&#8216;</font><font color="#ff40ff">\&#8217;\&#8217;</font><font color="#ffff00">&#8216;</font><font color="#ffff00">/g;</font><br /> <br />
<font color="#ffff00">28 </font><font color="#ffff00">&nbsp;&nbsp;s/</font><font color="#ff40ff">\\</font><font color="#ffff00">n/\n/g;</font><br /> <br />
<font color="#ffff00">29 </font><font color="#ffff00">&nbsp;&nbsp;s/</font><font color="#ff40ff">\)</font><font color="#ffff00">,</font><font color="#ff40ff">\(</font><font color="#ffff00">/</font><font color="#ff40ff">\)</font><font color="#ffff00">;\n$a</font><font color="#ff40ff">\(</font><font color="#ffff00">/g;</font><br /> <br />
<font color="#ffff00">30 </font><font color="#ffff00">}</font><br /> <br />
<font color="#ffff00">31 </font><font color="#ffff00">&#8216;</font>&nbsp;<font color="#ffff00">&gt;</font>&nbsp;<font color="#ff40ff">$1</font>.sql<br /> <br />
<font color="#ffff00">32 </font>cat <font color="#ff40ff">$1</font>.sql | sqlite3 <font color="#ff40ff">$1</font>.db <font color="#ffff00">&gt;</font>&nbsp;<font color="#ff40ff">$1</font>.err<br /> <br />
<font color="#ffff00">33 </font><font color="#00ffff">ERRORS</font>=<font color="#ff40ff">cat </font><font color="#ff40ff">$1</font><font color="#ff40ff">.err </font><font color="#ffff00">|</font><font color="#ff40ff">&nbsp;wc -l</font><br /> <br />
<font color="#ffff00">34 </font><font color="#ffff00">if </font><font color="#ffff00">[</font>&nbsp;<font color="#ff40ff">$ERRORS</font>&nbsp;<font color="#ffff00">==</font>&nbsp;<font color="#ffff00">0</font>&nbsp;<font color="#ffff00">]</font><font color="#ffff00">;</font>&nbsp;<font color="#ffff00">then</font><br /> <br />
<font color="#ffff00">35 </font>&nbsp;&nbsp;<font color="#ffff00">echo</font><font color="#ffff00">&nbsp;</font><font color="#ffff00">&quot;</font><font color="#ffff00">Conversion completed without error. Output file: </font><font color="#ff40ff">$1</font><font color="#ffff00">.db</font><font color="#ffff00">&quot;</font><br /> <br />
<font color="#ffff00">36 </font>&nbsp;&nbsp;<font color="#ffff00">rm</font>&nbsp;<font color="#ff40ff">$1</font>.sql<br /> <br />
<font color="#ffff00">37 </font>&nbsp;&nbsp;<font color="#ffff00">rm</font>&nbsp;<font color="#ff40ff">$1</font>.err<br /> <br />
<font color="#ffff00">38 </font><font color="#ffff00">else</font><br /> <br />
<font color="#ffff00">39 </font>&nbsp;&nbsp;<font color="#ffff00">echo</font><font color="#ffff00">&nbsp;</font><font color="#ffff00">&quot;</font><font color="#ffff00">There were errors during conversion.&nbsp;&nbsp;Please review </font><font color="#ff40ff">$1</font><font color="#ffff00">.err and </font><font color="#ff40ff">$1</font><font color="#ffff00">.sql for details.</font><font color="#ffff00">&quot;</font><br /> <br />
<font color="#ffff00">40 </font><font color="#ffff00">fi</font><br /> <br />
<font color="#ffff00">41 </font> # 来源 http://www.sqlite.org/cvstrac/wiki?p=ConverterTools <br /> 
</p></blockquote>
<p><strong>转换步骤: </strong> </p>
<blockquote style="font-style:normal;"><p>
#导出WordPress数据库<br />
user@localhost:~$ mysqldump -u root -p &#8211;compatible=ansi &#8211;skip-opt wordpress &gt; MyBlog.sql</p>
<p>#转换.sql至SQLite数据库文件<br />
user@localhost:~$ sh mysql2sqlite.sh MyBlog.sql</p>
<p>user@localhost:~$ mv MyBlog.db /srv/httpd/wordpress/wp-content/database/MyBlog.sqlite
</p></blockquote>
<p>注: 这个脚本应急还行,但是布署会成问题(转换的字段类型偏差),建议手工校对表结构,添加索引。最后,在linux上,得把sqlite文件的读写权限赋予httpd用户。</p>
]]></content:encoded>
			<wfw:commentRss>http://mifunny.info/convert-mysql-to-sqlite-script-330.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>编译一个适合自己的MySQL &#8211; MySQL邯郸学步</title>
		<link>http://mifunny.info/complie-a-mysql-only-for-you-327.html</link>
		<comments>http://mifunny.info/complie-a-mysql-only-for-you-327.html#comments</comments>
		<pubDate>Mon, 01 Feb 2010 13:19:50 +0000</pubDate>
		<dc:creator>LD</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[64位]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[大佛Linux]]></category>
		<category><![CDATA[编译]]></category>

		<guid isPermaLink="false">http://mifunny.info/complie-a-mysql-only-for-you-327.html</guid>
		<description><![CDATA[为什么需要编译MySQL ? 性能! 那么不费话 开始: ###以 MySQL 5.1.42 为例 #tar xvf mysql-5.1.42.tar.gz #cd mysql-5.1.42/ #./configure &#8211;prefix=/usr/local/mysql51 ### 只定安装目录 &#8211;with-embedded-server &#8211;enable-assembler &#8211;with-mysqld-ldflags=-all-static &#8211;with-client-ldflags=-all-static ### 静态编译 &#8211;without-debug &#8211;without-docs &#8211;without-man &#8211;without-readline ### 舍去不必要的东东 &#8211;with-charset=utf8 &#8211;with-collation=utf8_general_ci ### 指定编码,建议使用utf8, 默认latin1 &#8211;with-extra-charsets=complex ### 添加支持的编码, 根据自己的需求指定 &#8211;enable-thread-safe-client ### 线程安全 &#8211;enable-local-infile &#8211;with-ssl &#8211;with-libwrap ### 附加网络安全支持 &#8211;with-plugins=innobase,heap ### 支持 Innodb 及内存表 ###可以不只定系统平台, 编译程序会自检; 如果指定, [...]]]></description>
			<content:encoded><![CDATA[<p> 为什么需要编译MySQL ? 性能! 那么不费话 开始:</p>
<blockquote style="font-style:normal;"><p>
  ###以 MySQL 5.1.42 为例<br />
#tar xvf mysql-5.1.42.tar.gz <br />
#cd mysql-5.1.42/</p>
<p>#./configure &#8211;prefix=/usr/local/mysql51  ### 只定安装目录<br />
  &#8211;with-embedded-server &#8211;enable-assembler &#8211;with-mysqld-ldflags=-all-static &#8211;with-client-ldflags=-all-static  ### 静态编译<br />
  &#8211;without-debug &#8211;without-docs &#8211;without-man &#8211;without-readline ### 舍去不必要的东东<br />
  &#8211;with-charset=utf8 &#8211;with-collation=utf8_general_ci ### 指定编码,建议使用utf8, 默认latin1<br />
  &#8211;with-extra-charsets=complex ### 添加支持的编码, 根据自己的需求指定<br />
  &#8211;enable-thread-safe-client  ### 线程安全<br />
  &#8211;enable-local-infile &#8211;with-ssl &#8211;with-libwrap   ### 附加网络安全支持<br />
  &#8211;with-plugins=innobase,heap   ### 支持 Innodb 及内存表<br />
  ###可以不只定系统平台, 编译程序会自检; 如果指定, Like: &#8211;with-system-type=i686-redhat-linux-gnu &#8211;with-machine-type=i686-redhat-linux-gnu </p>
<p>#make<br />
#sudo make install
</p></blockquote>
<p>编译MySQL 是很轻松的事, 毕竟没有烦琐的配置测试就可以提升不少性能.</p></p>
]]></content:encoded>
			<wfw:commentRss>http://mifunny.info/complie-a-mysql-only-for-you-327.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>迁移 Innodb 共享表空间至独立表空间 &#8211; MySQL邯郸学步</title>
		<link>http://mifunny.info/switch-innodb-share-to-separate-table-space-326.html</link>
		<comments>http://mifunny.info/switch-innodb-share-to-separate-table-space-326.html#comments</comments>
		<pubDate>Mon, 01 Feb 2010 12:58:33 +0000</pubDate>
		<dc:creator>LD</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Innodb]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[共享表空间]]></category>
		<category><![CDATA[独立表空间]]></category>

		<guid isPermaLink="false">http://mifunny.info/switch-innodb-share-to-separate-table-space-326.html</guid>
		<description><![CDATA[关于 MySQL 中的 Innodb 引擎就不多说了, 毕竟除了MyISAM 之外, 它的应用最广泛. Innodb 存储数据有两种方式: 共享表空间 和 独立表空间. 顾名思义, 共享表空间 就是把所有数据库数据放在一个或多个文件中( 这种方式的话,使用裸设备倒是很方便); 独立表空间 就是采用和MyISAM 想同的方式, 每个表拥有一个独立的数据文件( .idb )。 在服务器资源有限,单表数据不是特别多的情况下, 独立表空间明显比共享方式效率更高. 但是MySQL 默认是共享表空间, 现在LD 来演示一下转换方法. ### 备份数据库, mysqldump 参数请根据自个儿情况修改 #mysqldump -uroot -p123456 -A &#8211;opt &#62; backup.sql ### 停止服务器 #sudo /etc/rc.d/mysqld stop ### 清空数据 #sudo rm -rf /var/mysql/data/* ### 重新生成表结构, 修改权限 #sudo [...]]]></description>
			<content:encoded><![CDATA[<p>关于 MySQL 中的 Innodb 引擎就不多说了, 毕竟除了MyISAM 之外, 它的应用最广泛. Innodb 存储数据有两种方式: 共享表空间 和 独立表空间. 顾名思义, 共享表空间 就是把所有数据库数据放在一个或多个文件中( 这种方式的话,使用裸设备倒是很方便); 独立表空间 就是采用和MyISAM 想同的方式, 每个表拥有一个独立的数据文件( .idb )。</p>
<p>在服务器资源有限,单表数据不是特别多的情况下, 独立表空间明显比共享方式效率更高. 但是MySQL 默认是共享表空间, 现在LD 来演示一下转换方法. </p>
<p><span id="more-326"></span></p>
<blockquote style="font-style:normal;"><p>
  ### 备份数据库, mysqldump 参数请根据自个儿情况修改<br />
#mysqldump -uroot -p123456 -A &#8211;opt &gt; backup.sql</p>
<p>  ### 停止服务器<br />
#sudo /etc/rc.d/mysqld stop</p>
<p>### 清空数据<br />
#sudo rm -rf /var/mysql/data/*</p>
<p>### 重新生成表结构, 修改权限<br />
#sudo mysql_install_db<br />
#sudo chown mysql:mysql -R /var/mysql/data/</p>
<p>### <b>关键:</b> 修改配置<br />
#sudo vim /etc/mysql/my.cnf<br />
### [mysqld] 段添加 innodb_file_per_table</p>
<p>### 启动MySQL, 修改数据库用户授权<br />
#sudo /etc/rc.d/mysqld start <br />
#mysqladmin -uroot password &#8217;123456&#8242;</p>
<p>### 导回数据<br />
#mysql -uroot -p123456 &lt; backup.sql
</p></blockquote>
<p>OK 大功告成! [mysqld] 有个很有用的配置项 memlock :使MySQL 不写入Swap. 可惜只有在运行MySQL 的用户具有root 权限才行.</p>
</p>
<p>Query Cache 在以内容为主的需求下表现很不错, 但业务逻辑一复杂就拖后腿,郁闷ing, set global query_cache_size = 0; 可以运行时关闭Query Cache.</p>
]]></content:encoded>
			<wfw:commentRss>http://mifunny.info/switch-innodb-share-to-separate-table-space-326.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>处理三角关系MySQL数据库的备份和数据迁移</title>
		<link>http://mifunny.info/complex-mysql-cases-316.html</link>
		<comments>http://mifunny.info/complex-mysql-cases-316.html#comments</comments>
		<pubDate>Sat, 26 Dec 2009 14:26:32 +0000</pubDate>
		<dc:creator>LD</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[三角关系]]></category>
		<category><![CDATA[备份]]></category>
		<category><![CDATA[数据库]]></category>
		<category><![CDATA[迁移]]></category>

		<guid isPermaLink="false">http://mifunny.info/complex-mysql-cases-316.html</guid>
		<description><![CDATA[遇到这么一个情况: 数据库A 依赖数据库B, B依赖数据库C, C又依赖A. 我称之为 三角关系. 最终要完成数据结构的升级. 其实这个case中, 一共牵涉到12个数据库,为了说明清楚, 只以数据库 A B C 为例. 完成升级,包括: 保留原数据; 替换所有存储过程, 函数, 触发器, 视图; 升成必要数据, 插入配置数据; 把过程理顺一下: 导出新数据库A,B,C 的结构; 倒出新数据库A,B,C的存储过程,视图; 单独导出新数据库A,B,C 的触发器; 只导出旧数据库A,B,C 的数据; 重建A,B,C 结构, 导入旧数据(可以用VIM适当调整数据), 导入存储过程,视图,函数; 导入A,B,C 的触发器; 升成必要的数据(python 脚本+存储过程 的方案不错!); 把基本代码写一下, 根据不同情况修改: 3.1 导出表结构 mysqldump -uroot -p&#8217;123456&#8242; &#8211;default-character-set=utf8 &#8211;add-drop-database &#8211;add-drop-table &#8211;opt -l &#8211;no-data -B A [...]]]></description>
			<content:encoded><![CDATA[<p>遇到这么一个情况: 数据库A 依赖数据库B, B依赖数据库C, C又依赖A. 我称之为 三角关系. 最终要完成数据结构的升级. 其实这个case中, 一共牵涉到12个数据库,为了说明清楚, 只以数据库 A B C 为例.</p>
<p>完成升级,包括:
<ol style="list-style-type: decimal;">
<li>保留原数据;
  </li>
<li>替换所有存储过程, 函数, 触发器, 视图;
  </li>
<li>升成必要数据, 插入配置数据;
  </li>
</ol>
<p>  <span id="more-316"></span>把过程理顺一下:
<ol style="list-style-type: decimal;">
<li>导出新数据库A,B,C 的结构;
    </li>
<li>倒出新数据库A,B,C的存储过程,视图;
    </li>
<li>单独导出新数据库A,B,C 的触发器;
    </li>
<li>只导出旧数据库A,B,C 的数据;
    </li>
<li>重建A,B,C 结构, 导入旧数据(可以用VIM适当调整数据), 导入存储过程,视图,函数;
    </li>
<li>导入A,B,C 的触发器;
    </li>
<li>升成必要的数据(python 脚本+存储过程 的方案不错!);
    </li>
</ol>
<p>把基本代码写一下, 根据不同情况修改:</p>
<p> 3.1 导出表结构<br />
mysqldump -uroot -p&#8217;123456&#8242; &#8211;default-character-set=utf8 &#8211;add-drop-database &#8211;add-drop-table &#8211;opt -l &#8211;no-data -B A B C | sed &#8216;s/AUTO_INCREMENT=[0-9]*\s//g&#8217; &gt; structure.sql<br />
最后的sed 可以把auto_increment 去除, 为什么? 不多说.</p>
<p> 3.2 导出数据 <br />
mysqldump -uroot -p&#8217;123456&#8242; -c &#8211;no-create-db &#8211;no-create-info -B A B C &gt; data.sql<br />
如果数据库编码不同, 不能加 &#8211;skip-opt</p>
<p> 3.3 导出存储过程/函数<br />
SELECT * FROM mysql.proc WHERE db in(&#8216;A&#8217;,'B&#8217;,'C&#8217;);</p>
<p> 3.4 导出触发器<br />
mysqldump -uwgz -p&#8217;123456&#8242; &#8211;default-character-set=utf8 &#8211;skip-opt -l &#8211;no-create-db &#8211;no-create-info &#8211;no-data &#8211;trigger -B A B C &gt; trigger.sql</p>
<p> 3.5 删除触发器<br />
drop trigger /*!50032 if exists */ `A`.`XXOO`;<br />
&#8230;&#8230; 这里可以改进, 以后有空再说吧.</p>
<p> 3.6 建立表结构, 倒入旧数据, 导入存储过程,函数,触发器;</p>
<p> 3.7 生成必要的数据<br />
存储过程 + Python 脚本</p>
<p></p>
<p>后记: 本想详写, 但成熟的DBA 一定会有一套自己的备份、还原、升级脚本, 这里只点个意思, 仅此而已.</p>
]]></content:encoded>
			<wfw:commentRss>http://mifunny.info/complex-mysql-cases-316.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MERGE例子中的union搜索优化</title>
		<link>http://mifunny.info/optimization-for-an-union-select-305.html</link>
		<comments>http://mifunny.info/optimization-for-an-union-select-305.html#comments</comments>
		<pubDate>Sat, 07 Nov 2009 10:02:41 +0000</pubDate>
		<dc:creator>LD</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Study notes]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Union优化]]></category>
		<category><![CDATA[主键]]></category>

		<guid isPermaLink="false">http://mifunny.info/optimization-for-an-union-select-305.html</guid>
		<description><![CDATA[在 MERGE存储引擎的简单测试 – MySQL邯郸学步 一文中,有一个Union SELECT, 极其消耗时间, 仔细分析会发现,使用的搜索条件对应字段是TIMESTAMP, 索引几乎没用. 那么我们能不能绕开时间字段,使用作为主键的自增字段object_id 呢? 就单纯示例上这种情况,是可以的. 请看下面的存储过程: &#160;1 DELIMITER $$ &#160;2 &#160;3 DROP&#160;PROCEDURE&#160;IF&#160;EXISTS&#160;`testMERGE`.`unionSelect`$$ &#160;4 CREATE&#160;PROCEDURE&#160;`testMERGE`.`unionSelect` (IN&#160;startTime CHAR(16), IN&#160;endTime CHAR(16)) &#160;5 BEGIN &#160;6 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;/* 表test1结果集的总数，结果集开始ID， 结束ID */ &#160;7 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DECLARE t1_count BIGINT DEFAULT&#160;0;&#160;&#160;&#160;&#160; &#160;8 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DECLARE t1_startId BIGINT DEFAULT&#160;0;&#160;&#160; &#160;9 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DECLARE t1_endId BIGINT DEFAULT&#160;0;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 10 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DECLARE t2_count BIGINT DEFAULT&#160;0; 11 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DECLARE t2_startId [...]]]></description>
			<content:encoded><![CDATA[<p>在 <a href="http://mifunny.info/test-merge-in-mysql-5139-304.html" rel="bookmark" title="Permanent Link to MERGE存储引擎的简单测试 – MySQL邯郸学步">MERGE存储引擎的简单测试 – MySQL邯郸学步</a> 一文中,有一个Union SELECT, 极其消耗时间, 仔细分析会发现,使用的搜索条件对应字段是TIMESTAMP, 索引几乎没用.  那么我们能不能绕开时间字段,使用作为主键的自增字段object_id 呢? 就单纯示例上这种情况,是可以的. 请看下面的存储过程:</p>
<p><span id="more-305"></span><br />
<font color="#ffff00">&nbsp;1 </font>DELIMITER $$<br />
<font color="#ffff00">&nbsp;2 </font><br />
<font color="#ffff00">&nbsp;3 </font><font color="#ffff00">DROP</font>&nbsp;<font color="#ff40ff">PROCEDURE</font>&nbsp;<font color="#ff40ff">IF</font>&nbsp;<font color="#ffff00">EXISTS</font>&nbsp;`testMERGE`.`unionSelect`$$<br />
<font color="#ffff00">&nbsp;4 </font><font color="#ffff00">CREATE</font>&nbsp;<font color="#ff40ff">PROCEDURE</font>&nbsp;`testMERGE`.`unionSelect` (<font color="#ffff00">IN</font>&nbsp;startTime <font color="#00ff00">CHAR</font>(<font color="#ff6060">16</font>), <font color="#ffff00">IN</font>&nbsp;endTime <font color="#00ff00">CHAR</font>(<font color="#ff6060">16</font>))<br />
<font color="#ffff00">&nbsp;5 </font><font color="#ff40ff">BEGIN</font><br />
<font color="#ffff00">&nbsp;6 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#8080ff">/* 表test1结果集的总数，结果集开始ID， 结束ID */</font><br />
<font color="#ffff00">&nbsp;7 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DECLARE t1_count BIGINT <font color="#ff40ff">DEFAULT</font>&nbsp;<font color="#ff6060">0</font>;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<font color="#ffff00">&nbsp;8 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DECLARE t1_startId BIGINT <font color="#ff40ff">DEFAULT</font>&nbsp;<font color="#ff6060">0</font>;&nbsp;&nbsp; <br />
<font color="#ffff00">&nbsp;9 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DECLARE t1_endId BIGINT <font color="#ff40ff">DEFAULT</font>&nbsp;<font color="#ff6060">0</font>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<font color="#ffff00">10 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DECLARE t2_count BIGINT <font color="#ff40ff">DEFAULT</font>&nbsp;<font color="#ff6060">0</font>;<br />
<font color="#ffff00">11 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DECLARE t2_startId BIGINT <font color="#ff40ff">DEFAULT</font>&nbsp;<font color="#ff6060">0</font>;&nbsp;&nbsp; <br />
<font color="#ffff00">12 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DECLARE t2_endId BIGINT <font color="#ff40ff">DEFAULT</font>&nbsp;<font color="#ff6060">0</font>;<br />
<font color="#ffff00">13 </font><br />
<font color="#ffff00">14 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#8080ff">/* 先确定两个结果集的开始、结束ID，判断小集合; */</font><br />
<font color="#ffff00">15 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">SELECT</font>&nbsp;object_id <font color="#ff40ff">INTO</font>&nbsp;t1_startId <font color="#ff40ff">FROM</font>&nbsp;t1 <font color="#ff40ff">WHERE</font>&nbsp;date_format(updated, <font color="#ff6060">&#8216;%Y-%m-%d&#8217;</font>) &gt;= startTime <font color="#ff40ff">ORDER</font>&nbsp;<font color="#ff40ff">BY</font>&nbsp;object_id LIMIT <font color="#ff6060">1</font>;<br />
<font color="#ffff00">16 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">SELECT</font>&nbsp;object_id <font color="#ff40ff">INTO</font>&nbsp;t1_endId <font color="#ff40ff">FROM</font>&nbsp;t1 <font color="#ff40ff">WHERE</font>&nbsp;date_format(updated, <font color="#ff6060">&#8216;%Y-%m-%d&#8217;</font>) &lt;= endTime <font color="#ff40ff">ORDER</font>&nbsp;<font color="#ff40ff">BY</font>&nbsp;object_id <font color="#ff40ff">DESC</font>&nbsp;LIMIT <font color="#ff6060">1</font>;<br />
<font color="#ffff00">17 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">SET</font>&nbsp;t1_count = t1_endId &#8211; t1_startId;<br />
<font color="#ffff00">18 </font><br />
<font color="#ffff00">19 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">SELECT</font>&nbsp;object_id <font color="#ff40ff">INTO</font>&nbsp;t2_startId <font color="#ff40ff">FROM</font>&nbsp;t2 <font color="#ff40ff">WHERE</font>&nbsp;date_format(updated, <font color="#ff6060">&#8216;%Y-%m-%d&#8217;</font>) &gt;= startTime <font color="#ff40ff">ORDER</font>&nbsp;<font color="#ff40ff">BY</font>&nbsp;object_id LIMIT <font color="#ff6060">1</font>;<br />
<font color="#ffff00">20 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">SELECT</font>&nbsp;object_id <font color="#ff40ff">INTO</font>&nbsp;t2_endId <font color="#ff40ff">FROM</font>&nbsp;t2 <font color="#ff40ff">WHERE</font>&nbsp;date_format(updated, <font color="#ff6060">&#8216;%Y-%m-%d&#8217;</font>) &lt;= endTime <font color="#ff40ff">ORDER</font>&nbsp;<font color="#ff40ff">BY</font>&nbsp;object_id <font color="#ff40ff">DESC</font>&nbsp;LIMIT <font color="#ff6060">1</font>;<br />
<font color="#ffff00">21 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">SET</font>&nbsp;t2_count = t2_endId &#8211; t2_startId;<br />
<font color="#ffff00">22 </font><br />
<font color="#ffff00">23 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#8080ff">/* 小集合驱动大集合;&nbsp;&nbsp;利用主键object_id作为搜索条件！ */</font><br />
<font color="#ffff00">24 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff40ff">IF</font>&nbsp;t1_count &lt; t2_count <font color="#ff40ff">THEN</font><br />
<font color="#ffff00">25 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">SELECT</font>&nbsp;* <font color="#ff40ff">FROM</font>&nbsp;t1 <font color="#ff40ff">WHERE</font>&nbsp;object_id <font color="#ffff00">BETWEEN</font>&nbsp;t1_startId <font color="#ffff00">AND</font>&nbsp;(t1_endId+<font color="#ff6060">1</font>) <br />
<font color="#ffff00">26 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">UNION</font>&nbsp;<font color="#ffff00">ALL</font>&nbsp;<font color="#ffff00">SELECT</font>&nbsp;* <font color="#ff40ff">FROM</font>&nbsp;t2 <font color="#ff40ff">WHERE</font>&nbsp;object_id <font color="#ffff00">BETWEEN</font>&nbsp;t2_startId <font color="#ffff00">AND</font>&nbsp;(t2_endId+<font color="#ff6060">1</font>) <br />
<font color="#ffff00">27 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff40ff">ORDER</font>&nbsp;<font color="#ff40ff">BY</font>&nbsp;updated <font color="#ff40ff">DESC</font>&nbsp;LIMIT <font color="#ff6060">0</font>,<font color="#ff6060">50</font>;<br />
<font color="#ffff00">28 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff40ff">ELSE</font><br />
<font color="#ffff00">29 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">SELECT</font>&nbsp;* <font color="#ff40ff">FROM</font>&nbsp;t2 <font color="#ff40ff">WHERE</font>&nbsp;object_id <font color="#ffff00">BETWEEN</font>&nbsp;t2_startId <font color="#ffff00">AND</font>&nbsp;(t2_endId+<font color="#ff6060">1</font>)<br />
<font color="#ffff00">30 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">UNION</font>&nbsp;<font color="#ffff00">ALL</font>&nbsp;<font color="#ffff00">SELECT</font>&nbsp;* <font color="#ff40ff">FROM</font>&nbsp;t1 <font color="#ff40ff">WHERE</font>&nbsp;object_id <font color="#ffff00">BETWEEN</font>&nbsp;t1_startId <font color="#ffff00">AND</font>&nbsp;(t1_endId+<font color="#ff6060">1</font>) <br />
<font color="#ffff00">31 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff40ff">ORDER</font>&nbsp;<font color="#ff40ff">BY</font>&nbsp;updated <font color="#ff40ff">DESC</font>&nbsp;LIMIT <font color="#ff6060">0</font>,<font color="#ff6060">50</font>;<br />
<font color="#ffff00">32 </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff40ff">END</font>&nbsp;<font color="#ff40ff">IF</font>;<br />
<font color="#ffff00">33 </font><br />
<font color="#ffff00">34 </font><font color="#ff40ff">END</font>$$<br />
<font color="#ffff00">35 </font><br />
<font color="#ffff00">36 </font>DELIMITER ;</p>
<p>
mysql&gt; call unionSelect(<font color="#ff6060">&#8217;2009-10-01&#8242;</font>, <font color="#ff6060">&#8217;2009-10-31&#8242;</font>);<br />
&nbsp;<font color="#8080ff">&#8212;&#8212;-&gt; </font><br />
Query OK, <font color="#ff6060">0</font>&nbsp;<font color="#ff40ff">rows</font>&nbsp;affected (<font color="#ff6060">0</font>.<font color="#ff6060">97</font>&nbsp;sec)<br />
多次执行，执行时间为维持在1s左右; 执行时间是原来的一半不到;<br />
</p>
<p>LD不是DBA，不过开发中消耗资源比较大的SELECT语句，尽量使用索引，尤其是唯一索引。</p>
]]></content:encoded>
			<wfw:commentRss>http://mifunny.info/optimization-for-an-union-select-305.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MERGE存储引擎的简单测试 – MySQL邯郸学步</title>
		<link>http://mifunny.info/test-merge-in-mysql-5139-304.html</link>
		<comments>http://mifunny.info/test-merge-in-mysql-5139-304.html#comments</comments>
		<pubDate>Sat, 31 Oct 2009 17:21:22 +0000</pubDate>
		<dc:creator>LD</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MERGE]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[存储引擎]]></category>
		<category><![CDATA[测试]]></category>

		<guid isPermaLink="false">http://mifunny.info/test-merge-in-mysql-5139-304.html</guid>
		<description><![CDATA[大多数时候,LD都看似很闲,所以看书也无目的性。最近看关于MySQL的东西，碰到MERGE这个存储引擎，做个小测试。 我其实只想知道一样东西，用UNION就可以合并两个查询，视图也能合并两张表数据，那么MERGE在合并表的数据后是否提供优化？ LD使用的MySQL是ArchLinux软件库中的，版本5.1.39, 配置文件默认，不做任何内存参数优化(因为使用的数据是真实的，而实际服务器上，运维也使用默认设置); 这两个表2个月前因为表字段的不同，执行一个union all的select语句要 260s 之久; 经过一番优化，已经缩短为2~3s, 但随着数据的增长，执行时间也在增加。LD一直在找解决方案，这么少的数据，还没达到100W，如果不能从SQL优化角度着手，只能从Linux系统和MySQL服务的配置想办法了。 废话不多说，Let&#8217;s Go。 一、原数据在InnoDB上的表现 1.1 第一张表 t1 , InnoDB 存储引擎, 50W条数据; mysql&#62; show create&#160;table&#160;t1; +&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+ &#124; Table&#160;&#160;&#160;&#160;&#160;&#160;&#124; Create&#160;Table&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#124; +&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+ &#124; t1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#124; CREATE&#160;TABLE&#160;`t1` ( &#160;&#160;`object_id` bigint(20) unsigned NOT&#160;NULL&#160;AUTO_INCREMENT, &#160;&#160;`content` TEXT NOT&#160;NULL&#160;COMMENT&#160;&#8216;内容&#8217;, &#160;&#160;`updated` timestamp NOT&#160;NULL&#160;DEFAULT&#160;CURRENT_TIMESTAMP COMMENT&#160;&#8216;更新时间&#8217;, &#160;&#160;PRIMARY KEY (`object_id`) &#160;) ENGINE=InnoDB AUTO_INCREMENT=1&#160;DEFAULT&#160;CHARSET=utf8 COMMENT=&#8216;测试表1&#8242;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#124; +&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+ mysql&#62; SELECT&#160;count(*) [...]]]></description>
			<content:encoded><![CDATA[<p>大多数时候,LD都看似很闲,所以看书也无目的性。最近看关于MySQL的东西，碰到MERGE这个存储引擎，做个小测试。<br />
我其实只想知道一样东西，用UNION就可以合并两个查询，视图也能合并两张表数据，那么MERGE在合并表的数据后是否提供优化？ </p>
<p> LD使用的MySQL是ArchLinux软件库中的，版本5.1.39, 配置文件默认，不做任何内存参数优化(因为使用的数据是真实的，而实际服务器上，运维也使用默认设置);</p>
<p>这两个表2个月前因为表字段的不同，执行一个union all的select语句要 260s 之久;  经过一番优化，已经缩短为2~3s, 但随着数据的增长，执行时间也在增加。LD一直在找解决方案，这么少的数据，还没达到100W，如果不能从SQL优化角度着手，只能从Linux系统和MySQL服务的配置想办法了。  废话不多说，Let&#8217;s Go。</p>
<p><span id="more-304"></span><br />
<strong>一、原数据在InnoDB上的表现</strong><br />
<font color="#ff6060">1.1</font> 第一张表 t1 , InnoDB 存储引擎, 50W条数据;<br />
mysql&gt; show <font color="#ffff00">create</font>&nbsp;<font color="#ff40ff">table</font>&nbsp;t1;<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+</font><br />
| <font color="#ff40ff">Table</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <font color="#ffff00">Create</font>&nbsp;<font color="#ff40ff">Table</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+</font><br />
| t1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <font color="#ffff00">CREATE</font>&nbsp;<font color="#ff40ff">TABLE</font>&nbsp;`t1` (<br />
&nbsp;&nbsp;`object_id` bigint(<font color="#ff6060">20</font>) unsigned <font color="#ffff00">NOT</font>&nbsp;<font color="#ff40ff">NULL</font>&nbsp;AUTO_INCREMENT,<br />
&nbsp;&nbsp;`content` TEXT <font color="#ffff00">NOT</font>&nbsp;<font color="#ff40ff">NULL</font>&nbsp;<font color="#ffff00">COMMENT</font>&nbsp;<font color="#ff6060">&#8216;内容&#8217;</font>,<br />
&nbsp;&nbsp;`updated` timestamp <font color="#ffff00">NOT</font>&nbsp;<font color="#ff40ff">NULL</font>&nbsp;<font color="#ff40ff">DEFAULT</font>&nbsp;CURRENT_TIMESTAMP <font color="#ffff00">COMMENT</font>&nbsp;<font color="#ff6060">&#8216;更新时间&#8217;</font>,<br />
&nbsp;&nbsp;PRIMARY KEY (`object_id`)<br />
&nbsp;) ENGINE=InnoDB AUTO_INCREMENT=<font color="#ff6060">1</font>&nbsp;<font color="#ff40ff">DEFAULT</font>&nbsp;CHARSET=utf8 <font color="#ffff00">COMMENT</font>=<font color="#ff6060">&#8216;测试表1&#8242;</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+</font><br />
mysql&gt; <font color="#ffff00">SELECT</font>&nbsp;count(*) <font color="#ff40ff">FROM</font>&nbsp;t1;<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;-+</font><br />
| count(*) |<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;-+</font><br />
|&nbsp;&nbsp; <font color="#ff6060">543360</font>&nbsp;|<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;-+</font><br />
<font color="#ff6060">1</font>&nbsp;<font color="#ff40ff">row</font>&nbsp;<font color="#ffff00">in</font>&nbsp;<font color="#ffff00">set</font>&nbsp;(<font color="#ff6060">3</font>.<font color="#ff6060">29</font>&nbsp;sec)</p>
<p>
<font color="#ff6060">1.2</font>第二张表 t2 , InnoDB 存储引擎, 12W条数据; <br />
mysql&gt; show <font color="#ffff00">create</font>&nbsp;<font color="#ff40ff">table</font>&nbsp;t2;<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+</font><br />
| <font color="#ff40ff">Table</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <font color="#ffff00">Create</font>&nbsp;<font color="#ff40ff">Table</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+</font><br />
| t2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <font color="#ffff00">CREATE</font>&nbsp;<font color="#ff40ff">TABLE</font>&nbsp;`t2` (<br />
&nbsp;&nbsp;`object_id` bigint(<font color="#ff6060">20</font>) unsigned <font color="#ffff00">NOT</font>&nbsp;<font color="#ff40ff">NULL</font>&nbsp;AUTO_INCREMENT,<br />
&nbsp;&nbsp;`content` TEXT <font color="#ffff00">NOT</font>&nbsp;<font color="#ff40ff">NULL</font>&nbsp;<font color="#ffff00">COMMENT</font>&nbsp;<font color="#ff6060">&#8216;内容&#8217;</font>,<br />
&nbsp;&nbsp;`updated` timestamp <font color="#ffff00">NOT</font>&nbsp;<font color="#ff40ff">NULL</font>&nbsp;<font color="#ff40ff">DEFAULT</font>&nbsp;CURRENT_TIMESTAMP <font color="#ffff00">COMMENT</font>&nbsp;<font color="#ff6060">&#8216;更新时间&#8217;</font>,<br />
&nbsp;&nbsp;PRIMARY KEY (`object_id`)<br />
&nbsp;) ENGINE=InnoDB AUTO_INCREMENT=<font color="#ff6060">1</font>&nbsp;<font color="#ff40ff">DEFAULT</font>&nbsp;CHARSET=utf8 <font color="#ffff00">COMMENT</font>=<font color="#ff6060">&#8216;测试表1&#8242;</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+</font><br />
mysql&gt; <font color="#ffff00">SELECT</font>&nbsp;count(*) <font color="#ff40ff">FROM</font>&nbsp;t2;<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;-+</font><br />
| count(*) |<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;-+</font><br />
|&nbsp;&nbsp; <font color="#ff6060">129315</font>&nbsp;|<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;-+</font><br />
<font color="#ff6060">1</font>&nbsp;<font color="#ff40ff">row</font>&nbsp;<font color="#ffff00">in</font>&nbsp;<font color="#ffff00">set</font>&nbsp;(<font color="#ff6060">0</font>.<font color="#ff6060">64</font>&nbsp;sec)</p>
<p>
<font color="#ff6060">1.3</font>对两张表进行UNION之后的结果 <br />
mysql&gt; <font color="#ffff00">SELECT</font>&nbsp;count(*) <font color="#ff40ff">AS</font>&nbsp;t2_sum <font color="#ff40ff">FROM</font>&nbsp;t2 <font color="#ff40ff">WHERE</font>&nbsp;updated <font color="#ffff00">BETWEEN</font>&nbsp;<font color="#ff6060">&#8217;2009-10-01&#8242;</font>&nbsp;<font color="#ffff00">AND</font>&nbsp;<font color="#ff6060">&#8217;2009-10-31&#8242;</font>&nbsp;;<br />
+<font color="#8080ff">&#8212;&#8212;&#8211;+</font><br />
| t2_sum |<br />
+<font color="#8080ff">&#8212;&#8212;&#8211;+</font><br />
|&nbsp;&nbsp;<font color="#ff6060">56926</font>&nbsp;|<br />
+<font color="#8080ff">&#8212;&#8212;&#8211;+</font><br />
<font color="#ff6060">1</font>&nbsp;<font color="#ff40ff">row</font>&nbsp;<font color="#ffff00">in</font>&nbsp;<font color="#ffff00">set</font>&nbsp;(<font color="#ff6060">0</font>.<font color="#ff6060">44</font>&nbsp;sec)<br />
mysql&gt; <font color="#ffff00">SELECT</font>&nbsp;count(*) <font color="#ff40ff">AS</font>&nbsp;t1_sum <font color="#ff40ff">FROM</font>&nbsp;t1 <font color="#ff40ff">WHERE</font>&nbsp;updated <font color="#ffff00">BETWEEN</font>&nbsp;<font color="#ff6060">&#8217;2009-10-01&#8242;</font>&nbsp;<font color="#ffff00">AND</font>&nbsp;<font color="#ff6060">&#8217;2009-10-31&#8242;</font>&nbsp;;<br />
+<font color="#8080ff">&#8212;&#8212;&#8211;+</font><br />
| t1_sum |<br />
+<font color="#8080ff">&#8212;&#8212;&#8211;+</font><br />
| <font color="#ff6060">234110</font>&nbsp;|<br />
+<font color="#8080ff">&#8212;&#8212;&#8211;+</font><br />
<font color="#ff6060">1</font>&nbsp;<font color="#ff40ff">row</font>&nbsp;<font color="#ffff00">in</font>&nbsp;<font color="#ffff00">set</font>&nbsp;(<font color="#ff6060">1</font>.<font color="#ff6060">82</font>&nbsp;sec)<br />
mysql&gt; <font color="#ffff00">SELECT</font>&nbsp;* <font color="#ff40ff">FROM</font>&nbsp;t2 <font color="#ff40ff">WHERE</font>&nbsp;updated <font color="#ffff00">BETWEEN</font>&nbsp;<font color="#ff6060">&#8217;2009-10-01&#8242;</font>&nbsp;<font color="#ffff00">AND</font>&nbsp;<font color="#ff6060">&#8217;2009-10-31&#8242;</font>&nbsp;<font color="#ffff00">UNION</font>&nbsp;<font color="#ffff00">ALL</font>&nbsp;<font color="#ffff00">SELECT</font>&nbsp;* <font color="#ff40ff">FROM</font>&nbsp;t1 <font color="#ff40ff">WHERE</font>&nbsp;updated&nbsp;&nbsp;<font color="#ffff00">BETWEEN</font>&nbsp;<font color="#ff6060">&#8217;2009-10-01&#8242;</font>&nbsp;<font color="#ffff00">AND</font>&nbsp;<font color="#ff6060">&#8217;2009-10-31&#8242;</font>&nbsp;<font color="#ff40ff">ORDER</font>&nbsp;<font color="#ff40ff">BY</font>&nbsp;updated <font color="#ff40ff">DESC</font>&nbsp;LIMIT <font color="#ff6060">0</font>,<font color="#ff6060">50</font>;<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;+</font><br />
|&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&nbsp;&nbsp;&nbsp;&nbsp;略&nbsp;&nbsp;&#8230;&nbsp;&nbsp; |<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;+</font><br />
<font color="#ff6060">50</font>&nbsp;<font color="#ff40ff">rows</font>&nbsp;<font color="#ffff00">in</font>&nbsp;<font color="#ffff00">set</font>&nbsp;(<font color="#ff6060">3</font>.<font color="#ff6060">42</font>&nbsp;sec)<br />
# 多执行几次，时间在<font color="#ff6060">2.6</font>&nbsp;~ <font color="#ff6060">3.5</font>&nbsp;之间徘徊</p>
<p>
<strong>二、把表类型改为MyISAM，再执行Select union</strong><br />
<font color="#ff6060">2.1</font>修改数据表类型<br />
mysql&gt; <font color="#ffff00">ALTER</font>&nbsp;<font color="#ff40ff">TABLE</font>&nbsp;t1 <font color="#ff40ff">type</font>&nbsp;= MyISAM;<br />
Query OK, <font color="#ff6060">543360</font>&nbsp;<font color="#ff40ff">rows</font>&nbsp;affected, <font color="#ff6060">1</font>&nbsp;warning (<font color="#ff6060">4</font>.<font color="#ff6060">68</font>&nbsp;sec)<br />
Records: <font color="#ff6060">543360</font>&nbsp;&nbsp;Duplicates: <font color="#ff6060">0</font>&nbsp;&nbsp;Warnings: <font color="#ff6060">0</font><br />
mysql&gt; <font color="#ffff00">ALTER</font>&nbsp;<font color="#ff40ff">TABLE</font>&nbsp;t2 <font color="#ff40ff">type</font>&nbsp;= MyISAM;<br />
Query OK, <font color="#ff6060">129315</font>&nbsp;<font color="#ff40ff">rows</font>&nbsp;affected, <font color="#ff6060">1</font>&nbsp;warning (<font color="#ff6060">1</font>.<font color="#ff6060">10</font>&nbsp;sec)<br />
Records: <font color="#ff6060">129315</font>&nbsp;&nbsp;Duplicates: <font color="#ff6060">0</font>&nbsp;&nbsp;Warnings: <font color="#ff6060">0</font></p>
<p><font color="#ff6060">2.2</font> 执行SELECT UNION <br />
mysql&gt; <font color="#ffff00">SELECT</font>&nbsp;* <font color="#ff40ff">FROM</font>&nbsp;t2 <font color="#ff40ff">WHERE</font>&nbsp;updated <font color="#ffff00">BETWEEN</font>&nbsp;<font color="#ff6060">&#8217;2009-10-01&#8242;</font>&nbsp;<font color="#ffff00">AND</font>&nbsp;<font color="#ff6060">&#8217;2009-10-31&#8242;</font>&nbsp;<font color="#ffff00">UNION</font>&nbsp;<font color="#ffff00">ALL</font>&nbsp;<font color="#ffff00">SELECT</font>&nbsp;* <font color="#ff40ff">FROM</font>&nbsp;t1 <font color="#ff40ff">WHERE</font>&nbsp;updated&nbsp;&nbsp;<font color="#ffff00">BETWEEN</font>&nbsp;<font color="#ff6060">&#8217;2009-10-01&#8242;</font>&nbsp;<font color="#ffff00">AND</font>&nbsp;<font color="#ff6060">&#8217;2009-10-31&#8242;</font>&nbsp;<font color="#ff40ff">ORDER</font>&nbsp;<font color="#ff40ff">BY</font>&nbsp;updated <font color="#ff40ff">DESC</font>&nbsp;LIMIT <font color="#ff6060">0</font>,<font color="#ff6060">50</font>;<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;+</font><br />
|&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&nbsp;&nbsp;&nbsp;&nbsp;略&nbsp;&nbsp;&#8230;&nbsp;&nbsp; |<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;+</font><br />
<font color="#ff6060">50</font>&nbsp;<font color="#ff40ff">rows</font>&nbsp;<font color="#ffff00">in</font>&nbsp;<font color="#ffff00">set</font>&nbsp;(<font color="#ff6060">2</font>.<font color="#ff6060">11</font>&nbsp;sec)<br />
# 多执行几次，时间在<font color="#ff6060">2.0</font>&nbsp;~ <font color="#ff6060">2.2</font>&nbsp;之间徘徊</p>
<p>
<strong>三、使用MERGE合并数据表</strong><br />
<font color="#ff6060">3.1</font>创建MERGE数据引擎的表 t3_merge <br />
mysql&gt; <font color="#ffff00">CREATE</font>&nbsp;<font color="#ff40ff">TABLE</font>&nbsp;`t3_merge` (<br />
&nbsp;&nbsp;&nbsp;&nbsp;-&gt; `object_id` bigint(<font color="#ff6060">20</font>) unsigned <font color="#ffff00">NOT</font>&nbsp;<font color="#ff40ff">NULL</font>&nbsp;AUTO_INCREMENT,<br />
&nbsp;&nbsp;&nbsp;&nbsp;-&gt; `content` TEXT <font color="#ffff00">NOT</font>&nbsp;<font color="#ff40ff">NULL</font>&nbsp;<font color="#ffff00">COMMENT</font>&nbsp;<font color="#ff6060">&#8216;内容&#8217;</font>,<br />
&nbsp;&nbsp;&nbsp;&nbsp;-&gt; `updated` timestamp <font color="#ffff00">NOT</font>&nbsp;<font color="#ff40ff">NULL</font>&nbsp;<font color="#ff40ff">DEFAULT</font>&nbsp;CURRENT_TIMESTAMP <font color="#ffff00">COMMENT</font>&nbsp;<font color="#ff6060">&#8216;更新时间&#8217;</font>,<br />
&nbsp;&nbsp;&nbsp;&nbsp;-&gt; PRIMARY KEY (`object_id`)<br />
&nbsp;&nbsp;&nbsp;&nbsp;-&gt; ) ENGINE=MERGE <font color="#ff40ff">DEFAULT</font>&nbsp;CHARSET=utf8 <font color="#ffff00">COMMENT</font>=<font color="#ff6060">&#8216;测试MERGE表3&#8242;</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p><font color="#ff6060">3.2</font>执行SELECT UNION  <br />
mysql&gt; <font color="#ffff00">SELECT</font>&nbsp;* <font color="#ff40ff">FROM</font>&nbsp;t3_merge <font color="#ff40ff">WHERE</font>&nbsp;updated <font color="#ffff00">BETWEEN</font>&nbsp;<font color="#ff6060">&#8217;2009-10-01&#8242;</font>&nbsp;<font color="#ffff00">AND</font>&nbsp;<font color="#ff6060">&#8217;2009-10-31&#8242;</font>&nbsp;<font color="#ff40ff">ORDER</font>&nbsp;<font color="#ff40ff">BY</font>&nbsp;updated <font color="#ff40ff">DESC</font>&nbsp;LIMIT <font color="#ff6060">0</font>,<font color="#ff6060">50</font>;<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;+</font><br />
|&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&nbsp;&nbsp;&nbsp;&nbsp;略&nbsp;&nbsp;&#8230;&nbsp;&nbsp; |<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;+</font><br />
<font color="#ff6060">50</font>&nbsp;<font color="#ff40ff">rows</font>&nbsp;<font color="#ffff00">in</font>&nbsp;<font color="#ffff00">set</font>&nbsp;(<font color="#ff6060">2</font>.<font color="#ff6060">37</font>&nbsp;sec)<br />
# 多执行几次，时间在<font color="#ff6060">1</font>.<font color="#ff6060">62</font>&nbsp;~ <font color="#ff6060">1</font>.<font color="#ff6060">78</font>&nbsp;之间徘徊</p>
<p>
<strong>四、测试视图性能 </strong><br />
mysql&gt; <font color="#ffff00">CREATE</font>&nbsp;<font color="#ff40ff">VIEW</font>&nbsp;t4_view <font color="#ff40ff">AS</font>&nbsp;<font color="#ffff00">SELECT</font>&nbsp;object_id, content, updated <font color="#ff40ff">FROM</font>&nbsp;t2 <font color="#ffff00">UNION</font>&nbsp;<font color="#ffff00">ALL</font>&nbsp;<font color="#ffff00">SELECT</font>&nbsp;object_id, content, updated <font color="#ff40ff">FROM</font>&nbsp;t1;<br />
Query OK, <font color="#ff6060">0</font>&nbsp;<font color="#ff40ff">rows</font>&nbsp;affected (<font color="#ff6060">0</font>.<font color="#ff6060">10</font>&nbsp;sec)<br />
mysql&gt; <font color="#ffff00">SELECT</font>&nbsp;* <font color="#ff40ff">FROM</font>&nbsp;t4_view <font color="#ff40ff">WHERE</font>&nbsp;updated <font color="#ffff00">BETWEEN</font>&nbsp;<font color="#ff6060">&#8217;2009-10-01&#8242;</font>&nbsp;<font color="#ffff00">AND</font>&nbsp;<font color="#ff6060">&#8217;2009-10-31&#8242;</font>&nbsp;<font color="#ff40ff">ORDER</font>&nbsp;<font color="#ff40ff">BY</font>&nbsp;updated <font color="#ff40ff">DESC</font>&nbsp;LIMIT <font color="#ff6060">0</font>,<font color="#ff6060">50</font>;<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;+</font><br />
|&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&nbsp;&nbsp;&nbsp;&nbsp;略&nbsp;&nbsp;&#8230;&nbsp;&nbsp; |<br />
+<font color="#8080ff">&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;+</font><br />
<font color="#ff6060">50</font>&nbsp;<font color="#ff40ff">rows</font>&nbsp;<font color="#ffff00">in</font>&nbsp;<font color="#ffff00">set</font>&nbsp;(<font color="#ff6060">4</font>.<font color="#ff6060">22</font>&nbsp;sec)<br />
# 多执行几次，时间在<font color="#ff6060">3.3</font>&nbsp;~ <font color="#ff6060">3.5</font>&nbsp;之间徘徊</p>
<p></p>
<p><strong>五、结论</strong></p>
<p>仅从最终平均执行时间上看，同时查询两张表的数据，merge胜出。 然而为了使用事务，真实数据表使用的是InnoDB，和第一步相同,而MERGE只支持MyISAM的联合。在这种情况中，如果数据表使用MyISAM，配合MERGE还是可取的一种方式(这里不说优化，因为是否真的优化还得再考量); </p>
<p>很多人认为MySQL会对视图有所优化，但实际使用中，你会发现：复杂的情况下使用视图，会托慢整个系统; 不如自己手工优化SQL语句，这时SQL语句也许会很复杂，但省下的性能开销，还是值得的。 </p>
]]></content:encoded>
			<wfw:commentRss>http://mifunny.info/test-merge-in-mysql-5139-304.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>多条件排序- MySQL邯郸学步</title>
		<link>http://mifunny.info/multi-order-condition-in-mysql-300.html</link>
		<comments>http://mifunny.info/multi-order-condition-in-mysql-300.html#comments</comments>
		<pubDate>Tue, 27 Oct 2009 13:39:47 +0000</pubDate>
		<dc:creator>LD</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Study notes]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[多条件排序]]></category>
		<category><![CDATA[排序]]></category>

		<guid isPermaLink="false">http://mifunny.info/multi-order-condition-in-mysql-300.html</guid>
		<description><![CDATA[通常在写SQL语句时会碰到需要对结果集进行排序，使用&#8217;order by&#8217;单个条件还行，那么多个条件怎么写？ 比如:先对时间逆序，再按编号排正序。要求第二次排序不打乱对时间的排序。 1 SELECT&#160;id,name,created,action FROM&#160;tbl_jobs ORDER&#160;BY&#160;created DESC, id LIMIT 15; 如上例,直接在&#8217;order by&#8217;接第二、第三条件即可，很方便。(很久之前LD还考虑过子查询，昏.)]]></description>
			<content:encoded><![CDATA[<p>通常在写SQL语句时会碰到需要对结果集进行排序，使用&#8217;order by&#8217;单个条件还行，那么多个条件怎么写？ 比如:先对时间逆序，再按编号排正序。要求第二次排序不打乱对时间的排序。</p>
<p><font color="#ffff00">1 </font><font color="#ffff00">SELECT</font>&nbsp;id,name,created,action <font color="#ff40ff">FROM</font>&nbsp;tbl_jobs <font color="#ff40ff">ORDER</font>&nbsp;<font color="#ff40ff">BY</font>&nbsp;created <font color="#ff40ff">DESC</font>, id LIMIT <font color="#ff6060">15</font>;</p>
<p>如上例,直接在&#8217;order by&#8217;接第二、第三条件即可，很方便。(很久之前LD还考虑过子查询，昏.)</p>
]]></content:encoded>
			<wfw:commentRss>http://mifunny.info/multi-order-condition-in-mysql-300.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用Python连接MySQL &#8211; MySQL邯郸学步</title>
		<link>http://mifunny.info/connect-to-mysql-with-python-296.html</link>
		<comments>http://mifunny.info/connect-to-mysql-with-python-296.html#comments</comments>
		<pubDate>Tue, 20 Oct 2009 13:55:41 +0000</pubDate>
		<dc:creator>LD</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[连接]]></category>

		<guid isPermaLink="false">http://mifunny.info/connect-to-mysql-with-python-296.html</guid>
		<description><![CDATA[使用Python并不能直接连接MySQL， 必须安装mysql-python软件包。对于Arch， 只需要 sudo pacman -Sy mysql-python 安装完连接库，直接调用就是，剩下的简单，就和其他语言操作数据库的形式相差无几.下面给出一个例子, 想了解更多，请在py终端打入help #!/usr/bin/env python # -*-coding:UTF-8-*- import MySQLdb conn = MySQLdb.Connection(db_host, db_user, db_passwd, db_name) cur = conn.cursor() # 执行SQL语句 cur.execute('SET NAMES utf8') conn.commit() # 查询 sql = "SELECT COUNT(*) FROM tbl_test" cur.execute(sql) row = cur.fetchone() # 执行存储过程 cur.callproc('CALL testPro()') conn.commit() cur.close() # FILE END. dp.SyntaxHighlighter.ClipboardSwf = 'http://mifunny.info/site/google-syntax-highlighter/Scripts/clipboard.swf'; dp.SyntaxHighlighter.HighlightAll('code');]]></description>
			<content:encoded><![CDATA[<p style="text-indent: 2em;">使用Python并不能直接连接MySQL， 必须安装mysql-python软件包。对于Arch， 只需要 sudo pacman -Sy mysql-python </p>
<p><span id="more-296"></span></p>
<p>安装完连接库，直接调用就是，剩下的简单，就和其他语言操作数据库的形式相差无几.下面给出一个例子, 想了解更多，请在py终端打入help </p>
<link rel="stylesheet" href="http://mifunny.info/site/google-syntax-highlighter/Styles/SyntaxHighlighter.css" type="text/css" media="screen" />
<pre name="code" class="python">

#!/usr/bin/env python
# -*-coding:UTF-8-*-
import MySQLdb

conn = MySQLdb.Connection(db_host, db_user, db_passwd, db_name)
cur = conn.cursor()

# 执行SQL语句
cur.execute('SET NAMES utf8')
conn.commit()

# 查询
sql = "SELECT COUNT(*) FROM tbl_test"
cur.execute(sql)
row = cur.fetchone()

# 执行存储过程
cur.callproc('CALL testPro()')
conn.commit()

cur.close()

# FILE END.
</pre>
<p><script type="text/javascript" src="http://mifunny.info/site/google-syntax-highlighter/Scripts/shCore.js"></script><br />
<script type="text/javascript" src="http://mifunny.info/site/google-syntax-highlighter/Scripts/shBrushPython.js"></script><br />
<script type="text/javascript">
dp.SyntaxHighlighter.ClipboardSwf = 'http://mifunny.info/site/google-syntax-highlighter/Scripts/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');
</script></p>
]]></content:encoded>
			<wfw:commentRss>http://mifunny.info/connect-to-mysql-with-python-296.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>存储过程中的简单事务处理 &#8211; MySQL邯郸学步</title>
		<link>http://mifunny.info/simple-transaction-in-procedure-289.html</link>
		<comments>http://mifunny.info/simple-transaction-in-procedure-289.html#comments</comments>
		<pubDate>Mon, 14 Sep 2009 09:45:09 +0000</pubDate>
		<dc:creator>LD</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[SQLEXCEPTION]]></category>
		<category><![CDATA[事务处理]]></category>
		<category><![CDATA[存储过程]]></category>

		<guid isPermaLink="false">http://mifunny.info/?p=289</guid>
		<description><![CDATA[很多资料中，对于事务的处理都很简单，抓捕SQL错误，仅仅是一个 @@error_count 吗？ 肯定不是。@@error_count 只记录上一次SQL操作的结果，对于存储过程中多条语句肯定是不行的。 那么，怎么才能保证在存储过程中正确的回滚呢？让我们先来看个例子： CREATE TABLE `test` (`id` int(11) NOT NULL AUTO_INCREMENT, `content` varchar(100), PRIMARY KEY (`id`) ); DELIMITER $$ DROP PROCEDURE IF EXISTS test_sp1 $$ CREATE PROCEDURE test_sp1( ) BEGIN START TRANSACTION; INSERT INTO test VALUES(NULL, 'test sql 001'); /* 第一条 insert 能执行 */ INSERT INTO test VALUES('1', 'test sql 002'); /* [...]]]></description>
			<content:encoded><![CDATA[<p style="text-indent: 2em;">很多资料中，对于事务的处理都很简单，抓捕SQL错误，仅仅是一个 @@error_count 吗？ 肯定不是。@@error_count 只记录上一次SQL操作的结果，对于存储过程中多条语句肯定是不行的。</p>
<p style="text-indent: 2em;">那么，怎么才能保证在存储过程中正确的回滚呢？让我们先来看个例子：</p>
<p><span id="more-289"></span></p>
<link rel="stylesheet" href="http://mifunny.info/site/google-syntax-highlighter/Styles/SyntaxHighlighter.css" type="text/css" media="screen" />
<pre name="code" class="sql">
CREATE TABLE `test` (`id` int(11) NOT NULL AUTO_INCREMENT,
	`content` varchar(100), PRIMARY KEY (`id`) );

DELIMITER $$
DROP PROCEDURE IF EXISTS  test_sp1 $$
CREATE PROCEDURE test_sp1( )
    BEGIN
        START TRANSACTION;
			INSERT INTO test VALUES(NULL, 'test sql 001');   /* 第一条 insert 能执行 */
			INSERT INTO test VALUES('1', 'test sql 002');  /* 第二条 insert，不能执行 */ 

        IF @@error_count = 0 THEN
            COMMIT;
        ELSE
            ROLLBACK;
        END IF;  

    END$$
DELIMITER ;
</pre>
<p>我们在MySQL客户端执行 CALL test_sp1(); 之后会发现，存储过程中第一条insert成功的执行了，而第二条执行没有执行，但是注意！ 这里发生了错误，而作为判断的 @@error_count 没有反应, ROLLBACK 不能回滚！</p>
<p>在我上一篇文章 《<a href="http://mifunny.info/half-of-the-stored-procedure-273.html" title="执行一半的存储过程 – MySQL邯郸学步" rel="bookmark">执行一半的存储过程 – MySQL邯郸学步</a>》中存储过程执行了一半， 而很不幸的，这里的 test_sp1() 也执行了一般，就好比我们PHP、JAVA、C++程序遇到错误一样，抛出error, 然后停止执行。 </p>
<p>之前使用PDO，在处理事务时，使用SQLException捕获SQL错误，然后处理； 按照这个推论，我们必须在MySQL存储过程中捕获SQL错误，最后判断是回滚(ROLLBACK)还是提交(COMMIT)。 所以存储过程可以改为：</p>
<pre name="code" class="sql">
DELIMITER $$
DROP PROCEDURE IF EXISTS  test_sp1 $$
CREATE PROCEDURE test_sp1( )
    BEGIN
	DECLARE t_error INTEGER DEFAULT 0;
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1;

		START TRANSACTION;
			INSERT INTO test VALUES(NULL, 'test sql 001');   /* 第一条 insert 能执行 */
			INSERT INTO test VALUES('1', 'test sql 002');  /* 第二条 insert，不能执行 */ 

        F txn_error = 1 THEN
			ROLLBACK;
		ELSE
			COMMIT;
		END IF;

    END$$
DELIMITER ;
</pre>
<p>第二个例子中，我们为test_sp1() 定义了一个 SQLEXCEPTION 参数 t_error， 在遇到SQL错误时，继续执行(CONTINUE); 如果执行状态没有错误，则提交，反之回滚！</p>
<p>如果存储过程A包含B， 那么最好只在A中定义事务； 记住，保证事务的原子性。</p>
<p>下面是我摘抄的，值得挤公车时慢慢品味：</p>
<blockquote><p>
1，保持事务短小  <br />
2，尽量避免事务中rollback  <br />
3，尽量避免savepoint  <br />
4，默认情况下，依赖于悲观锁  <br />
5，为吞吐量要求苛刻的事务考虑乐观锁  <br />
6，显示声明打开事务  <br />
7，锁的行越少越好，锁的时间越短越好  
</p></blockquote>
<p><script type="text/javascript" src="http://mifunny.info/site/google-syntax-highlighter/Scripts/shCore.js"></script><br />
<script type="text/javascript" src="http://mifunny.info/site/google-syntax-highlighter/Scripts/shBrushSql.js"></script><br />
<script type="text/javascript">
dp.SyntaxHighlighter.ClipboardSwf = 'http://mifunny.info/site/google-syntax-highlighter/Scripts/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');
</script></p>
]]></content:encoded>
			<wfw:commentRss>http://mifunny.info/simple-transaction-in-procedure-289.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

