gate_s

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

由于原来系统的分页方式,采用的是假分页,效率很低,且经常数据库超时报黄页。所以,最近都在寻找合适的分页优化方法。

原sql模型:

WITH    Records
          AS ( SELECT   ROW_NUMBER() OVER ( ORDER BY XXX DESC ) AS RecordNumber,
      RecordCount = COUNT(1) OVER ( ),
      ……
      ……
      ……
 
            FROM   table1
      WHERE  条件)
 
SELECT  *
    FROM    Records WITH ( NOLOCK )
    WHERE   RecordNumber BETWEEN 1 AND 15
 
目前找到的比较有效地优化方式,有两种,一种仍采取这种假分页方式,但是,将with中的select 字段拿到with外,具体如下:
假分页优化方式:
WITH    Records
          AS ( SELECT   ROW_NUMBER() OVER ( ORDER BY XXX DESC ) AS RecordNumber,
      RecordCount = COUNT(1) OVER ( ),
      id
            FROM   table1
      WHERE  条件)
 
SELECT    ……
      ……
      ……
            ,Records.*
    FROM    Records WITH ( NOLOCK )
    JoIN table1 WITH ( NOLOCK ) ON table1.partid = Records.partid
    WHERE   RecordNumber BETWEEN 1 AND 15
这种方式,因with中只是select索引字段,而wiht仅对一页需要的15条数据,select出所有字段,这样可以较好的提高数据库处理效率。
 
另外一种优化方式比较彻底,是采用top方式,进行真分页查询,效率提高非常明显,具体如下:
真分页优化方式:
SELECT TOP 页大小 * FROM table1 WHERE id >           (           SELECT ISNULL(MAX(id),0)           FROM                 (                 SELECT TOP 页大小*(页数-1) id FROM table1  WHERE  条件 ORDER BY id                 ) A           ) ORDER BY id
但是因为这种方式没法求的总数量,
所以,我又进行了改进,具体如下:
 
DECLARE @RecordCount INT; SET @RecordCount= (SELECT COUNT(1) FROM table1 WHERE  条件);
 
SELECT TOP 页大小 * FROM table1 WHERE id >           (           SELECT ISNULL(MAX(id),0)           FROM                 (                 SELECT TOP 页大小*(页数-1) id FROM table1  WHERE  条件 ORDER BY id                 ) A           ) ORDER BY id
 
就目前测试使用情况看,两种优化方式的优缺点:
假分页优化
优点:当select字段较大、较多,尤其是有类似varchar(max)类型时,提高性能明显;易于规范编写。
缺点:当数据量过大时,如数据集过百万时,仍有超时隐患。
 
真分页优化
优点:因是真分页方式,数据库处理效率非常快,效率是目前最高的。
缺点:当逻辑较复杂时,语句过于繁琐,不利于规范编写;且当表关联结构过于复杂,无统一关键字段时,将更加不便于编写。
为实现多关键字问题,又进行了改进,具体如下:
 
DECLARE @RecordCount INT; SET @RecordCount= (SELECT COUNT(1) FROM table1
             JOIN table2 on 1.id=2.tb_id
           WHERE  条件);
 
SELECT TOP 页大小 *
,@RecordCoun  as RecordCoun FROM table1
JOIN table2 on 1.id=2.tb_id WHERE NOT EXISTS ( SELECT 1           FROM                 (                 SELECT TOP 页大小*(页数-1)
          table1.id as tb1,
          table2 .id as tb2
       FROM table1 
       JOIN table2 on 1.id=2.tb_id
      WHERE  条件
      ORDER BY 1.id,2.id                 ) A
    WHERE A.tb1= 1.id and A.tb2=2.id           ) ORDER BY 1.id,2.id
posted on 2013-08-20 13:10  gate_s  阅读(322)  评论(0编辑  收藏  举报