高效的SQLSERVER分页方案

Sqlserver数据库分页查询一直是Sqlserver的短板,假设有表ARTICLE,字段ID、YEAR,数据53210条(客户真实数据,量不大),分页查询每页30条,查询第1500页(即第45001-45030条数据),字段ID聚集索引,YEAR无索引,Sqlserver版本:2008R2

第一种方案:
SELECT TOP 30 * FROM ARTICLE WHERE ID NOT IN(SELECT TOP 45000 ID FROM ARTICLE ORDER BY YEAR DESC, ID DESC) ORDER BY YEAR DESC,ID DESC

平均查询100次所需时间:45s

第二种方案:
SELECT * FROM (  SELECT TOP 30 * FROM (SELECT TOP 45030 * FROM ARTICLE ORDER BY YEAR DESC, ID DESC) f ORDER BY f.YEAR ASC, f.ID DESC) s ORDER BY s.YEAR DESC,s.ID DESC

平均查询100次所需时间:138S

第三种方案:
SELECT * FROM ARTICLE w1, 
(
    SELECT TOP 30 ID FROM 
    (
        SELECT TOP 50030 ID, YEAR FROM ARTICLE ORDER BY YEAR DESC, ID DESC
    ) w ORDER BY w.YEAR ASC, w.ID ASC
) w2 WHERE w1.ID = w2.ID ORDER BY w1.YEAR DESC, w1.ID DESC

平均查询100次所需时间:21S

第四种方案:
SELECT * FROM ARTICLE w1 
    WHERE ID in 
        (
            SELECT top 30 ID FROM 
            (
                SELECT top 45030 ID, YEAR FROM ARTICLE ORDER BY YEAR DESC, ID DESC
            ) w ORDER BY w.YEAR ASC, w.ID ASC
        ) 
    ORDER BY w1.YEAR DESC, w1.ID DESC

平均查询100次所需时间:20S

第五种方案:
SELECT w2.n, w1.* FROM ARTICLE w1, (  SELECT TOP 50030 row_number() OVER (ORDER BY YEAR DESC, ID DESC) n, ID FROM ARTICLE ) w2 WHERE w1.ID = w2.ID AND w2.n > 50000 ORDER BY w2.n ASC

平均查询100次所需时间:15S

在查询页数靠前时,效率3>4>5>2>1,页码靠后时5>4>3>1>2,再根据用户习惯,一般用户的检索只看最前面几页,因此选择3 4 5方案均可,若综合考虑方案5是最好的选择,但是要注意SQL2000不支持row_number()函数

总结分页SQL:
1、 使用两个select和两个order,双倒序:比如你有查找相关记录中10001-10020的20条记录。你先按照某字段排序,查找前10020条记录,形成数据集,再进行倒序查找前20条。这种方法比较简单,但进行多字段排序时,有时候会出现莫名奇妙的错误(可能我不够经验)。
2、 使用两个select,并产生临时序号:一样比如你有查找相关记录中10001-10020的20条记录。你首先查找所有相关数据,并增加新的列储存记录临时序号,形成数据集,再根据查找数据集,而条件增加了临时序号在10001-10020之间。这种方法必须使用陌生的产生临时序号函数,而产生临时序号的函数只有SQL Serrver 2005 才支持。
3、 创建临时表,产生临时ID:一样比如你有查找相关记录中10001-10020的20条记录。你可以首先创建一个只有自增ID和你需要查找相关记录的自己字段的临时表,并将你查找记录的主键填入临时表。再查询临时表,增加条件临时序号在10001-10020之间。最后删除临时表。这种方法最复杂,但可扩展的空间比较大,性能的优化的潜力也应该比较强。
----------------两个select 加两个order,双倒序(27秒钟)
select top 20 * from (select top 349980 * from Test where type >5 order by type desc) as temp order by type desc
"select top”+numcount+” * from Jokes where id not in ( select top "+numcount*(当前页-1)+" id from Jokes order by id desc ) order by id desc";
 
----------------两个select 产生临时序号(1秒钟)
select * from (
select * ,ROW_NUMBER() OVER(ORDER BY type,ID) AS RowRank from Test where type >5) as temp
where RowRank between 350001 and 350020
----------------临时表,create+insert+select+drop(3秒钟)
----------------临时表,create+insert+select(2秒钟)
CREATE TABLE #PageIndexForUsers
(
    IndexID int IDENTITY (0, 1) NOT NULL,
    ID int
)
INSERT INTO #PageIndexForUsers (ID)
SELECT ID
FROM Test
WHERE type >5
ORDER BY type,ID

SELECT T.* FROM Test T, #PageIndexForUsers p
WHERE  p.ID = T.ID AND
       p.IndexId between 350000 and 350019

drop table #PageIndexForUsers
运行结果占用了时间是第一种方式用了27秒,第二种用了1秒,第三种不加drop用了2秒,加drop用了3秒。
 
查询 31到40条记录 的各种玩法
1. 如果ID连续
select * from A where ID between 31 and 40 
2. 如果ID不连续,提供三种写法
--两次对表A查询效率较低
select top 10 * from A where ID not in (select top 30 ID from A)
 
--外层查询没有对表A查询,效率大有提高
select top 10 * from (select top 40 * from A order by ID) as t order by t.ID desc
 
--ROW_NUMBER()函数效率更高,sqlserver2005以及以上版本中才可以使用
select * from (select ROW_NUMBER() over(order by ID) as ‘sequence‘,A.* from A ) as t where t.sequence between 31 and 40
 
--查询16-20之间记录
select * from (select ROW_NUMBER() over(order by ID) as ‘sequence‘,ent_pos.* from ent_pos ) as t where t.sequence between 16 and 20
 
select top 5 * from (select top 20 * from ent_pos order by ID) as t order by t.ID desc
 
select top 5 * from ent_pos where ID not in (select top 15 ID from ent_pos)
 
--如果是海量数据做查询的话,这个是更高效的,这个不错
select top 10 * from A where id in
(select top 10 id from (select top 40 id from A order by ID desc) as t order by t.ID )
order by A.ID desc
--这哥们给出了sql2012的新写法,我机器上没装这么前卫的工具,在我老大的机器上测试可行,性能效率暂不明确
SELECT * FROM A Order by ID OFFSET 30 ROWS FETCH NEXT 10 ROWS ONLY

时间: 2024-08-03 03:27:40

高效的SQLSERVER分页方案的相关文章

真正高效的SQLSERVER分页查询(多种方案)

Sqlserver数据库分页查询一直是Sqlserver的短板,闲来无事,想出几种方法,假设有表ARTICLE,字段ID.YEAR...(其他省略),数据53210条(客户真实数据,量不大),分页查询每页30条,查询第1500页(即第45001-45030条数据),字段ID聚集索引,YEAR无索引,Sqlserver版本:2008R2 第一种方案.最简单.普通的方法: 复制代码代码如下: SELECT TOP 30 * FROM ARTICLE WHERE ID NOT IN(SELECT TO

高效的SQLSERVER分页查询的几种示例分析

Sqlserver数据库分页查询一直是Sqlserver的短板,闲来无事,想出几种方法,假设有表ARTICLE,字段ID.YEAR...(其他省略),数据53210条(客户真实数据,量不大),分页查询每页30条,查询第1500页(即第45001-45030条数据),字段ID聚集索引,YEAR无索引,Sqlserver版本:2008R2 第一种方案.最简单.普通的方法: 1 SELECT TOP 30 * FROM ARTICLE WHERE ID NOT IN(SELECT TOP 45000

高效的SQLSERVER分页查询(推荐)

Sqlserver数据库分页查询一直是Sqlserver的短板,闲来无事,想出几种方法,假设有表ARTICLE,字段ID.YEAR...(其他省略),数据53210条(客户真实数据,量不大),分页查询每页30条,查询第1500页(即第45001-45030条数据),字段ID聚集索引,YEAR无索引,Sqlserver版本:2008R2 第一种方案.最简单.普通的方法: 代码如下: [sql] view plaincopyprint? SELECT TOP 30 * FROM ARTICLE WH

高效的SQLSERVER分页查询(转载)

Sqlserver数据库分页查询一直是Sqlserver的短板,闲来无事,想出几种方法,假设有表ARTICLE,字段ID.YEAR...(其他省略),数据53210条(客户真实数据,量不大),分页查询每页30条,查询第1500页(即第45001-45030条数据),字段ID聚集索引,YEAR无索引,Sqlserver版本:2008R2 第一种方案.最简单.普通的方法: SELECT TOP 30 * FROM ARTICLE WHERE ID NOT IN(SELECT TOP 45000 ID

高效的SQLSERVER分页查询

Sqlserver数据库分页查询一直是Sqlserver的短板,闲来无事,想出几种方法,假设有表ARTICLE,字段ID.YEAR...(其他省略),数据53210条(客户真实数据,量不大),分页查询每页30条,查询第1500页(即第45001-45030条数据),字段ID聚集索引,YEAR无索引,Sqlserver版本:2008R2 第一种方案.最简单.普通的方法: SELECT TOP 30 * FROM ARTICLE WHERE ID NOT IN (SELECT TOP 45000 I

SqlServer分页总结-摘抄

sqlserver2008不支持关键字limit ,所以它的分页sql查询语句将不能用mysql的方式进行,幸好sqlserver2008提供了top,rownumber等关键字,这样就能通过这几个关键字实现分页. 下面是本人在网上查阅到的几种查询脚本的写法: 几种sqlserver2008高效分页sql查询语句 top方案: sql code: select top 10 * from table1 where id not in(select top 开始的位置 id from table1

sqlserver 分页查询总结

sqlserver2008不支持关键字limit ,所以它的分页sql查询语句将不能用mysql的方式进行,幸好sqlserver2008提供了top,rownumber等关键字,这样就能通过这几个关键字实现分页. 下面是本人在网上查阅到的几种查询脚本的写法: 几种sqlserver2008高效分页sql查询语句top方案:sql code: select top 10 * from table1where id not in(select top 开始的位置 id from table1) m

SQLserver分页查询实例

Sqlserver数据库分页查询一直是Sqlserver的短板,闲来无事,想出几种方法,假设有表ARTICLE,字段ID.YEAR...(其他省略),数据53210条(客户真实数据,量不大),分页查询每页30条,查询第1500页(即第45001-45030条数据),字段ID聚集索引,YEAR无索引,Sqlserver版本:2008R2 第一种方案.最简单.普通的方法: SELECT TOP 30 * FROM ARTICLE WHERE ID NOT IN(SELECT TOP 45000 ID

sqlserver分页;mysql分页;orcale分页 的sql 查询语句

1 一,sqlserver分页: 2 SELECT TOP (每页显示的数据条数) *FROM 表名 WHERE (ID NOT IN (SELECT TOP ((当前页码 -1)*每页显示的数据条数 -1) ID FROM 表名 AS 表名1_1 ORDER BY ID)) ORDER BY ID; 3 二:mysql分页 4 select * from 表名 where id limit((当前页码 -1)*每页显示的数据条数,当前页码 * 每页显示的数据条数); 5 三:orcale分页