mysql limit 分页分页查询求该

有没有让mysql记录进行分页显示的sql语句
只求一条sql
09-11-04 &匿名提问
1、数据库操作平台的开放性  Oracle能在所有主要的平台(其中包括Windows)上运行,并且完全支持所有的工业标准,所以,客户可以利用很多种第三方应用程序、工具、网关和管理实用程序。Oracle采用开放策略,它使得客户可以选择一种最适合他们特定需要的解决方案。SQL Server只在Windows上运行,Microsoft这种专有策略的目标是将客户锁定到Windows环境中。由于SQL Server紧密的捆绑在Windows平台上,所以,只有随着Windows操作系统可靠性、开放性以及性能的改善,SQL Server的开放性和可靠性才能进一步提高。   2、性能价格比   选择数据库产品,首先要考虑数据库产品的性能,同时还关心究竟要花多少钱才能建立并运行一套Oracle或SQL Server数据库系统。这些钱不仅包含最初购置软件、硬件的费用,还包含了维护、培训费用。两家公司都宣称自己的性能价格比好,实际上,Oracle公司侧重于产品的可靠性和实用性方面,而Microsoft公司更侧重于产品价格方面。由于操作系统的原因,普遍认为SQL Server的可靠性较差,而另一方面Oracle的初始花费则相对较高,尤其是在考虑工具软件的因素时,与SQL Server免费提供工具软件相比,Oracle更显价格不菲。所以,在考虑该使用什么软件时,要根据自己的业务需求和基础设施来综合考虑。   3、工具软件   使数据库易于安装、使用和管理――组合在一起称为“操作简单”――是一个减少成本的关键因素。Microsoft产品具有易于使用的美誉,在很多方面也确实如此,SQL Server就得益于让人感到使用起来比较容易。SQL Server企业管理器(Enterprise Manager)是SQL Server软件的一个组成部分,给用户提供了一个集成的管理控制台来集中管理多个服务器。Oracle也由自己的企业管理器,它的性能随着版本的提高有所改善,有些方面甚至超过了SQL Server企业管理器,但它安装较为困难,有些较好的组件还需另外购买。SQL Server与Windows操作系统无缝集成, Microsoft公司总是尽可能将所有的软件功能捆扎在一起,除非用户还需要其他用处的操作软件包,否则功能已足够使用了。而Oracle公司将工具软件交给第三方软件商来开发,花费高,尤其在别人的软件免费提供的情况下,这种问题就更显突出。   4、数据库性能   那种数据库更快?这其实是一个很难回答的问题,因为存在许多不定因素,包括处理类型、数据分布以及硬件基础设施等。一些经验表明在长时间运行大量事务方面Oracle数据库要优于SQL Server,但在集群技术等方面,SQL Server比Oracle数据库要好一些。  5、价格:SQL Server不仅需要一个数据库,还需要一个不断升级、不断打补丁的WINDOWS系列操作系统。实际是买一强买一。  6、平台系统:ORACLE支持所有的平台,所有的CPU类型。UNIX平台稳定性得到大家的一致认可。  7、服务:Oracle数据库应用的强大,应用的深度和广度。  8、PL/SQL vs T-SQL T-SQ不支持位图索引,居于函数的索引,分区索引,对象,不支持嵌入java模式。  9、Oracle具有良好的性能调整参数和范围。  10、价格更便宜。  11、TPC-C测试最佳,良好的性价比。  12、方便灵活的管理和安装。  13、OLAP数据分析强大。
请登录后再发表评论!mysql分页原理和高效率的mysql分页查询语句
转载 & & 作者:
这篇文章主要介绍了mysql分页原理和高效率的mysql分页查询语句,大家参考使用吧
以前我在mysql中分页都是用的 limit 这样的方式,我相信你也是吧,但是要提高效率,让分页的代码效率更高一些,更快一些,那我们又该怎么做呢?
第一部分:看一下分页的基本原理:
代码如下:mysql explain SELECT * FROM message ORDER BY id DESC LIMIT 10000, 20***************** 1. row **************id: 1select_type: SIMPLEtable: messagetype: indexpossible_keys: NULLkey: PRIMARYkey_len: 4ref: NULLrows: 10020Extra:1 row in set (0.00 sec)
对上面的mysql语句说明:limit 10000,20的意思扫描满足条件的10020行,扔掉前面的10000行,返回最后的20行,问题就在这里,如果是limit ,需要扫描100100行,在一个高并发的应用里,每次查询需要扫描超过10W行,性能肯定大打折扣。文中还提到limit n性能是没问题的,因为只扫描n行。
第二部分:根据雅虎的几位工程师带来了一篇Efficient Pagination Using MySQL的报告内容扩展:在文中提到一种clue的做法,给翻页提供一些线索,比如还是SELECT * FROM message ORDER BY id DESC,按id降序分页,每页20条,当前是第10页,当前页条目id最大的是1020,最小的是1000,如果我们只提供上一页、下一页这样的跳转(不提供到第N页的跳转),那么在处理上一页的时候SQL语句可以是: 代码如下:SELECT * FROM message WHERE id&1020 ORDER BY id ASC LIMIT 20;//下一页
处理下一页的时候SQL语句可以是: 代码如下:SELECT * FROM message WHERE id&1000 ORDER BY id DESC LIMIT 20;//上一页
不管翻多少页,每次查询只扫描20行。
缺点是只能提供上一页、下一页的链接形式,但是我们的产品经理非常喜欢“上一页 1 2 3 4 5 6 7 8 9 下一页”这样的链接方式,怎么办呢?
如果LIMIT m,n不可避免的话,要优化效率,只有尽可能的让m小一下,我们扩展前面的clue做法,还是SELECT * FROM message ORDER BY id DESC,按id降序分页,每页20条,当前是第10页,当前页条目id最大的是2519,最小的是2500;
当是第10页的SQL如下: 代码如下:SELECT * FROM tb_goods_info WHERE auto_id &=2500 ORDER BY auto_id ASC LIMIT 0,20比如要跳到第9页,SQL语句可以这样写: 代码如下:SELECT * FROM tb_goods_info WHERE auto_id &2500 ORDER BY auto_id desc LIMIT 0,20比如要跳到第8页,SQL语句可以这样写: 代码如下:SELECT * FROM tb_goods_info WHERE auto_id &2500 ORDER BY auto_id desc LIMIT 20,20比如要跳到第7页,SQL语句可以这样写: 代码如下:SELECT * FROM tb_goods_info WHERE auto_id &2500 ORDER BY auto_id desc LIMIT 40,20跳转到第11页: 代码如下:SELECT * FROM tb_goods_info WHERE auto_id &2519 ORDER BY auto_id asc LIMIT 0,20跳转到第12页: 代码如下:SELECT * FROM tb_goods_info WHERE auto_id &2519 ORDER BY auto_id asc LIMIT 20,20跳转到第13页: 代码如下:SELECT * FROM tb_goods_info WHERE auto_id &2519 ORDER BY auto_id asc LIMIT 40,20
原理还是一样,记录住当前页id的最大值和最小值,计算跳转页面和当前页相对偏移,由于页面相近,这个偏移量不会很大,这样的话m值相对较小,大大减少扫描的行数。其实传统的limit m,n,相对的偏移一直是第一页,这样的话越翻到后面,效率越差,而上面给出的方法就没有这样的问题。
注意SQL语句里面的ASC和DESC,如果是ASC取出来的结果,显示的时候记得倒置一下。
已在60W数据总量的表中测试,效果非常明显
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具Mysql中分页查询的两个解决方法比较
转载 & & 作者:
本篇文章介绍了,Mysql中分页查询的两个解决方法比较。需要的朋友参考下
mysql中分页查询有两种方式, 一种是使用COUNT(*)的方式,具体代码如下
代码如下:SELECT COUNT(*) FROM foo WHERE b = 1; SELECT a FROM foo WHERE b = 1 LIMIT 100,10; 另外一种是使用SQL_CALC_FOUND_ROWS
代码如下:SELECT SQL_CALC_FOUND_ROWS a FROM foo WHERE b = 1 LIMIT 100, 10; SELECT FOUND_ROWS(); 第二种方式调用SQL_CALC_FOUND_ROWS之后会将WHERE语句查询的行数放在FOUND_ROWS()之中,第二次只需要查询FOUND_ROWS()就可以查出有多少行了。
讨论这两种方法的优缺点:首先原子性讲,第二种肯定比第一种好。第二种能保证查询语句的原子性,第一种当两个请求之间有额外的操作修改了表的时候,结果就自然是不准确的了。而第二种则不会。但是非常可惜,一般页面需要进行分页显示的时候,往往并不要求分页的结果非常准确。即分页返回的total总数大1或者小1都是无所谓的。所以其实原子性不是我们分页关注的重点。
下面看效率。这个非常重要,分页操作在每个网站上的使用都是非常大的,查询量自然也很大。由于无论哪种,分页操作必然会有两次sql查询,于是就有很多很多关于两种查询性能的比较:
SQL_CALC_FOUND_ROWS真的很慢么?
http://hi.baidu.com/thinkinginlamp/item/b122fdaea5ba23f
To SQL_CALC_FOUND_ROWS or not to SQL_CALC_FOUND_ROWS?
http://www.mysqlperformanceblog.com//to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/
老王这篇文章里面有提到一个covering index的概念,简单来说就是怎样才能只让查询根据索引返回结果,而不进行表查询
具体看他的另外一篇文章:
MySQL之Covering Index
http://hi.baidu.com/thinkinginlamp/item/1b9aaf09014acce0f45ba6d3
实验结合这几篇文章,做的实验:
代码如下:CREATE TABLE IF NOT EXISTS `foo` ( `a` int(10) unsigned NOT NULL AUTO_INCREMENT, `b` int(10) unsigned NOT NULL, `c` varchar(100) NOT NULL, PRIMARY KEY (`a`), KEY `bar` (`b`,`a`) ) ENGINE=MyISAM; 注意下这里是使用b,a做了一个索引,所以查询select * 的时候是不会用到covering index的,select a才会使用到covering index 代码如下:&?php $host = '192.168.100.166'; $dbName = 'test'; $user = 'root'; $password = ''; $db = mysql_connect($host, $user, $password) or die('DB connect failed'); mysql_select_db($dbName, $db); & echo '==========================================' . "\r\n"; $start = microtime(true); for ($i =0; $i&1000; $i++) { &&& mysql_query("SELECT SQL_NO_CACHE COUNT(*) FROM foo WHERE b = 1"); &&& mysql_query("SELECT SQL_NO_CACHE a FROM foo WHERE b = 1 LIMIT 100,10"); } $end = microtime(true); echo $end - $start . "\r\n"; echo '==========================================' . "\r\n"; $start = microtime(true); for ($i =0; $i&1000; $i++) { &&& mysql_query("SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS a FROM foo WHERE b = 1 LIMIT 100, 10"); &&& mysql_query("SELECT FOUND_ROWS()"); } $end = microtime(true); echo $end - $start . "\r\n"; echo '==========================================' . "\r\n"; $start = microtime(true); for ($i =0; $i&1000; $i++) { &&& mysql_query("SELECT SQL_NO_CACHE COUNT(*) FROM foo WHERE b = 1"); &&& mysql_query("SELECT SQL_NO_CACHE * FROM foo WHERE b = 1 LIMIT 100,10"); } $end = microtime(true); echo $end - $start . "\r\n"; echo '==========================================' . "\r\n"; $start = microtime(true); for ($i =0; $i&1000; $i++) { &&& mysql_query("SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS * FROM foo WHERE b = 1 LIMIT 100, 10"); &&& mysql_query("SELECT FOUND_ROWS()"); } $end = microtime(true); echo $end - $start . "\r\n";返回的结果:和老王里面文章说的是一样的。第四次查询SQL_CALC_FOUND_ROWS由于不仅是没有使用到covering index,也需要进行全表查询,而第三次查询COUNT(*),且select * 有使用到index,并没进行全表查询,所以有这么大的差别。
总结PS: 另外提醒下,这里是使用MyISAM会出现三和四的查询差别这么大,但是如果是使用InnoDB的话,就不会有这么大差别了。
所以我得出的结论是如果数据库是InnoDB的话,我还是倾向于使用SQL_CALC_FOUND_ROWS
结论:SQL_CALC_FOUND_ROWS和COUNT(*)的性能在都使用covering index的情况下前者高,在没使用covering index情况下后者性能高。所以使用的时候要注意这个。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
基本这种表现,我们没有必要浪费一条COUNT(*)查询。新办法其实很简单,不去统计总页数,而告诉客户端是否到达了最后一页。要告诉客户端是否到达了最后一页,只需要每次多查询一行记录。function page_friend($page = 1, $page_size = 8) {
global $user;
if ($page & 1) {
$page = 1;
//$page_size + 1,多取一行记录
$result = db_query(
"SELECT * FROM friends WHERE uid = %d ORDER BY fuid LIMIT %d, %d",
($user-&uid, ($page - 1) * $page_size, $page_size + 1)
$friends = ();
while ($f = db_fecth_object($result)) {
$friends[] = $f;
$page_is_last = true;
if (($friends) &= $page_size + 1) {
$page_is_last = false;
($friends);
'page'&& &=& $page,
'page_size' =& $page_size,
'page_is_last' =& $page_is_last,
'items' =& $friends
); }缺点:不能够显示总页码数,不能随意翻到指定页,只能上下翻页。优点:每次请求都省去了一条COUNT查询,节约了服务器资源。能不能再快一点当一个数据库表过于庞大,LIMIT offset, length中的offset值过大,则SQL查询语句会非常缓慢,你需增加order by,并且order by字段需要建立索引。如果使用子查询去优化LIMIT的话,则子查询必须是连续的,某种意义来讲,子查询不应该有where条件,where会过滤数据,使数据失去连续性。如果你查询的记录比较大,并且数据传输量比较大,比如包含了text类型的field,则可以通过建立子查询。SELECT id,title,content FROM items WHERE id IN (SELECT id FROM items ORDER BY id limit );如果limit语句的offset较大,你可以通过传递pk键值来减小offset = 0,这个主键最好是int类型并且auto_incrementSELECT * FROM users WHERE uid & 456891 ORDER BY uid LIMIT 0, 10;这条语句,大意如下:SELECT * FROM users WHERE uid &=& (SELECT uid FROM users ORDER BY uid limit ) limit 0, 10;如果limit的offset值过大,用户也会翻页疲劳,你可以设置一个offset最大的,超过了可以另行处理,一般连续翻页过大,用户体验很差,则应该提供更优的用户体验给用户。
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'MySQL 分页查询优化 LIMIT与COUNT优化',
blogAbstract:'& 老方法传统分页查询,一般通过COUNT()函数事先获知总记录数据$amountselect count(*) as amout from tbl_name where uid = 1然后可以通过ceil($amount / $page_size) 最终可以求知一共有多少页,告之用户。',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:9,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}151被浏览17,881分享邀请回答14添加评论分享收藏感谢收起4添加评论分享收藏感谢收起}

我要回帖

更多关于 mysql limit 分页 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信