<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post//</link>
<title><![CDATA[[转]高效的MySQL分页，精华，Gaston聊了下记录下来.]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Wed, 29 Apr 2009 09:04:23 +0000</pubDate> 
<guid>http://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	其实本质是：<br/>Mysql查询从以往常规的的Limit：<br/>$offset*($page-1),$offset <br/>0，20<br/>20，20<br/>40，20<br/>........<br/>变为了：<br/>永远的：<br/>0，20 ，但前面有一个：where id>动态的数值，这个id是有索引的，所以，查询起来更快一些。<br/>这里的Id是经过计算后的一个数值，主要是它用到了索引，所以在大数据量下快了不是一星半点。<br/>=========================================================<br/><br/><br/><br/>PERCONA PERFORMANCE CONFERENCE 2009上，来自雅虎的几位工程师带来了一篇”Efficient Pagination Using MySQL“的报告，有很多亮点，本文是在原文基础上的进一步延伸。<br/><br/>首先看一下分页的基本原理：<br/><br/>mysql> explain SELECT * FROM message ORDER BY id DESC LIMIT 10000, 20&#92;G<br/>***************** 1. row **************<br/>id: 1<br/>select_type: SIMPLE<br/>table: message<br/>type: index<br/>possible_keys: NULL<br/>key: PRIMARY<br/>key_len: 4<br/>ref: NULL<br/>rows: 10020<br/>Extra:<br/>1 row in set (0.00 sec)<br/><br/>limit 10000,20的意思扫描满足条件的10020行，扔掉前面的10000行，返回最后的20行，问题就在这里，如果是limit 100000,100，需要扫描100100行，在一个高并发的应用里，每次查询需要扫描超过10W行，性能肯定大打折扣。文中还提到limit n性能是没问题的，因为只扫描n行。<br/><br/>文中提到一种”clue”的做法，给翻页提供一些”线索”，比如还是SELECT * FROM message ORDER BY id DESC，按id降序分页，每页20条，当前是第10页，当前页条目id最大的是9527，最小的是9500，如果我们只提供”上一页”、”下一页”这样的跳转（不提供到第N页的跳转），那么在处理”上一页”的时候SQL语句可以是：<br/><br/>SELECT * FROM message WHERE id > 9527 ORDER BY id ASC LIMIT 20;<br/><br/>处理”下一页”的时候SQL语句可以是：<br/><br/>SELECT * FROM message WHERE id < 9500 ORDER BY id DESC LIMIT 20;<br/><br/>不管翻多少页，每次查询只扫描20行。<br/><br/>缺点是只能提供”上一页”、”下一页”的链接形式，但是我们的产品经理非常喜欢”<上一页 1 2 3 4 5 6 7 8 9 下一页>”这样的链接方式，怎么办呢？<br/><br/>如果LIMIT m,n不可避免的话，要优化效率，只有尽可能的让m小一下，我们扩展前面的”clue”做法，还是SELECT * FROM message ORDER BY id DESC，按id降序分页，每页20条，当前是第10页，当前页条目id最大的是9527，最小的是9500，比如要跳到第8页，我看的SQL语句可以这样写：<br/><br/>SELECT * FROM message WHERE id > 9527 ORDER BY id ASC LIMIT 20,20;<br/><br/>跳转到第13页：<br/><br/>SELECT * FROM message WHERE id < 9500 ORDER BY id DESC LIMIT 40,20;<br/><br/>原理还是一样，记录住当前页id的最大值和最小值，计算跳转页面和当前页相对偏移，由于页面相近，这个偏移量不会很大，这样的话m值相对较小，大大减少扫描的行数。其实传统的limit m,n，相对的偏移一直是第一页，这样的话越翻到后面，效率越差，而上面给出的方法就没有这样的问题。<br/><br/>注意SQL语句里面的ASC和DESC，如果是ASC取出来的结果，显示的时候记得倒置一下。<br/><br/>已在60W数据总量的表中测试，效果非常明显。<br/>
]]>
</description>
</item><item>
<link>http://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] [转]高效的MySQL分页，精华，Gaston聊了下记录下来.]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>