最近找到的一些分页优化的方法

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

原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 @ 2011-11-07 12:44  summer0311  阅读(387)  评论(0编辑  收藏  举报