月归档:二月 2016

大数据下的分页count引起的性能瓶颈及解决思路

在大部分系统里,数据呈现的时候都或多或少需要对数据进行分页处理之后再呈现,在数据量没有达到一定级别之前。无论如何实现分页都不会出现问题,而且分页实现的思路多种多样【sqlserver系统里使用ROW_NUMBER可以很方便的实现分页】,一旦数据量达到一定的级别之后,就会明显感觉到分页在呈现数据的时候有明显的延迟,产生性能瓶颈的根本原因是获取总记录数使用了聚合函数count,而又没有其它可以替代的方式。只能根据业务的进行简单的调整,使其能满足业务的需要。并没有打算实现一个完整的分页例子,也并不打算实现一个分页存储过程,只是将如何调整一个分页缓慢系统的思路整理了一下,大部分思路都是来自网路。 第一种: 这种方法最简单,也是最不灵活的一种,如果只是想要得到一张大表的总记录数,该方法是比较快速的。假如要获取某些条件的总记录数,该方法就不可行了。例子如下: SELECT rows FROM sysindexes WHERE id=OBJECT_ID(‘要查询的表名’) AND indid=1 第二种: 这种方法比较简单,并且也比较灵活。就是对获得的总记录数进行缓存。既然要缓存总记录数,一般都是key-value,value就是总记录数,以什么作为key,可以是传递过来的url,根据参数的不同进行缓存,使用该方法要将page参数过滤掉,也可以是根据获取总记录数的sql语句,对sqlcount字符串进行md5加密作为key【这种方法有个弊端,就是假如sql语句写的不够规范,随意的大小写或者相同几个where条件任意变换位置,获得的md5字符串将不一样】,可以将数据保存到应用程序内存中,也可以保存到文件中,还可以保存到数据库中,设置一个简单的过期策略。使用md5作为key的话,还可以将sql语句一并保存,这样还可以定时或者服务器空闲时更新相应语句的总记录数。 第三种: 对于只有上一页和下一页的分页思路,这种分页其实是不需要获得总记录数的。例如每页要显示20条记录,每次获取的时候只需获取21条,显示还是显示20条,判断一下获取的记录数只要大于20,就显示下一页即可。这种分页方式是最高效的。 第四种: 利用Set Rowcount函数快速滚动到我们要行数,并将id记下,进行分页。 DECLARE @page INT DECLARE @pagesize INT DECLARE @startindex INT DECLARE @id int SET @page=1 SET @pagesize=48 SET @startindex=(@page-1)*@pagesize+1 SET ROWCOUNT @startindex SELECT … 继续阅读

发表在 Net, 杂文 | 评论关闭