原文地址:http://www.cnblogs.com/yangyy753/archive/2013/01/23/2872753.html

数据的分页是我们再熟悉不过的功能了,各种各样的分页方式层出不穷。今天我把一些常见的存储过程分页列出来,再简单地测一下性能,算是对知识的总结,也是对您好想法的抛钻引玉。废话不多说,开始吧~~

1.首先建立一张测试表

--创建测试表
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[testTable](
[id] [int] IDENTITY(1,1) NOT NULL,
[testDate] [datetime] NOT NULL CONSTRAINT [DF_testTable_testDate] DEFAULT (getdate()),
[name] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
[description] [nchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
[orderColum] [float] NOT NULL,
CONSTRAINT [PK_testTable] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

2.循环插入1000000条测试数据

declare @i int
set @i = 1
while @i < 1000001
begin
INSERT INTO testTable([name],[description],[orderColum])
VALUES('PageTest', 'http://www.3ymao.com', @i * rand())
set @i = @i + 1
end

3.晒出我的系统硬件和软件(测试环境)

好吧,准备工作完成,开始进入主题(为了方便,以下代码我就不写成存储过程的方式来测试展示了)~~噔噔!首先登场的是我最常用的Not
IN

1)NOT IN

declare @timediff datetime
declare @pageIndex int
declare @pageSize int
declare @sql varchar(500)
set @pageIndex=1
set @pageSize=10
set @timediff=GetDATE()
set @sql='select top ('+cast(@pageSize as varchar)+') * from testTable where (id not in (
select top '+cast(@pageSize*(@pageIndex-1) as varchar)+' id from testTable order by id)) order by id'
exec(@sql)
select datediff(ms,@timediff,Getdate())

@pageIndex=1时,运行:0ms(给力啊!)

@pageIndex=50000时,运行:346ms(怎么50000页就不给力了)

@pageIndex=100000时,运行:326ms(怎么比50000页时还少了?)

2)MAX()

declare @timediff datetime
declare @pageIndex int
declare @pageSize int
declare @sql varchar(500)
set @timediff=GetDATE()
set @pageIndex=1
set @pageSize=10
set @sql='select top ('+cast(@pageSize as varchar)+') * from testTable where (id >= (select MAX(id) from (select top '+cast((@pageSize*(@pageIndex-1)+1) as varchar)+' id from testTable order by id) as a)) order by id'
exec(@sql)
select datediff(ms,@timediff,Getdate())

@pageIndex=1时,运行:0ms(也是很给力啊!)

@pageIndex=50000时,运行:123ms(不错)

@pageIndex=100000时,运行:220ms(页数和查询时间成正比)

3)Row_Number()

declare @timediff datetime
declare @pageIndex int
declare @pageSize int
declare @sql varchar(500)
set @timediff=GetDATE()
set @pageIndex=1
set @pageSize=10
set @sql='select * from (select *,row_number() over (order by id asc) as RowIndex from testTable) as IDWithRowNumber where RowIndex between '+cast(((@pageIndex-1)*@pageSize)+1 as varchar)+' and '+cast(@pageIndex*@pageSize as varchar)+''
exec(@sql)
select datediff(ms,@timediff,getdate())

@pageIndex=1时,运行:0ms(好吧……数据量小的时候都是这尿性)

@pageIndex=50000时,运行:280ms(略逊色)

@pageIndex=100000时,运行:580ms(这货居然也是页数和查询时间成正比!坑爹吧!)

4)临时表

declare @timediff datetime
declare @pageIndex int
declare @pageSize int
declare @sql varchar(500)
declare @str varchar(500)
set @timediff=GetDATE()
set @pageIndex=1
set @pageSize=10
set @str='with tempTable as (select ceiling((Row_number() over (order by id asc))/'+cast(@pageSize as varchar)+') as page_num,* from testTable)'
set @sql=@str+'select * from tempTable where page_num='+cast(@pageIndex-1 as varchar)+''
exec(@sql)
select datediff(ms,@timediff,getdate())

@pageIndex=1时,运行:280ms(不咧个是吧!这非主流啊)

@pageIndex=50000时,运行:280ms(这不科学……)

@pageIndex=100000时,运行:280ms(好吧,这货不受页数的影响,永远都这速度)

5)中间变量

declare @timediff datetime
declare @pageIndex int
declare @pageSize int
declare @count int
declare @id int
declare @sql varchar(500)
set @pageIndex=1
set @pageSize=10
select @id=0,@count=0,@timediff=GetDATE()
select @count=@count+1,@id=case when @count=(@pageIndex-1)*@pageSize then id else @id end from testTable order by id
set @sql='select top '+cast(@pageSize as varchar)+' * from testTable where id>'+cast(@id as varchar)+''
exec(@sql)
select datediff(ms,@timediff,getdate())

@pageIndex=1时,运行:360ms(哥,不是吧,才第一页你就这速度)

@pageIndex=50000时,运行:360ms(我大概猜到100000页时的速度了……)

@pageIndex=100000时,运行:360ms(好吧,又是不受页数影响的货)

从以上数据,我最后简单分析总结一下:

NOT IN:数据量小的时候,速度不错,但是数据量大的时候速度就有点逊色了,但是好在随着查询页数增大,他的速度还是不会改变多少。

MAX:小数据量的时候,它的速度是最快的,但是遗憾的是查询页数越大,速度则越慢。

Row_Number():性质与MAX相似,但是不比MAX速度快

临时表:不会因为查询页数而改变查询速度,只和数据量大小有关,个人觉得适合大数据量而且可能会查很大的页数时使用

中间变量:性质和临时表相似,但是逊色于临时表

(转)常见存储过程分页PK赛——简单测试分析常见存储过程分页速度的更多相关文章

  1. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(37)-文章发布系统④-百万级数据和千万级数据简单测试

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(37)-文章发布系统④-百万级数据和千万级数据简单测试 系列目录 我想测试EF在一百万条数据下的显示时间! ...

  2. F#之旅3 - F# PK C#:简单的求和

    原文链接:https://swlaschin.gitbooks.io/fsharpforfunandprofit/content/posts/fvsc-sum-of-squares.html Comp ...

  3. jsp、js分页功能的简单总结

    一.概述 首先,我们要明确为何需要分页技术,主要原因有以下: 1.分页可以提高客户体验度,适当地选择合适的数据条数,让页面显得更有条理,使得用户体验感良好,避免过多数据的冗余. 2.提高性能的需要.分 ...

  4. 简单实用的原生PHP分页类

    一款简单实用的原生PHP分页类,分页按钮样式简洁美观,页码多的时候显示“...”,也是挺多网站用的效果 核心分页代码 include_once("config.php"); req ...

  5. Web安全测试中常见逻辑漏洞解析(实战篇)

    Web安全测试中常见逻辑漏洞解析(实战篇) 简要: 越权漏洞是比较常见的漏洞类型,越权漏洞可以理解为,一个正常的用户A通常只能够对自己的一些信息进行增删改查,但是由于程序员的一时疏忽,对信息进行增删改 ...

  6. Linux实现树莓派3B的国密SM9算法交叉编译——(一)环境部署、简单测试与eclipse工程项目测试

    这篇文章主要介绍了交叉编译的实现,包括环境部署,并简单测试交叉编译环境是否安装成功. 一.交叉编译 在一个平台上生成另一个平台上的可执行代码.为什么要大费周折的进行交叉编译呢?一句话:不得已而为之.有 ...

  7. 简单测试linq to sql性能

         前些日子,做了一个物业收费系统,cs模式,用到了linq to sql 技术,这是我第一次使用这个东东写程序存取数据库,迷迷糊糊搞得一塌糊涂,当时有个同学他们找好的分页组件,然后写好了调用方 ...

  8. TODO:Golang UDP连接简单测试慎用Deadline

    TODO:Golang UDP连接简单测试慎用Deadline UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interco ...

  9. ThinkPHP3.2.3自带的分页用法--很简单实用

    把解压后的Page.class.php放入ThinkPHP/Extend/Library/ORG/Util/(如果没有请手动创建)目录下面.thinkphp 自带的分页非常好用美观,先看一下如下代码片 ...

随机推荐

  1. 记录一下 C51 里的位运算

    记录一下 C51 里的位运算 一篇上个世纪的文章<单片机的C语言中位操作用法>1 今天看到一个这样的运算,这相当于清了 XICFG. #define INT1IS1 0x80 #defin ...

  2. poj 3590 The shuffle Problem——DP+置换

    题目:http://poj.org/problem?id=3590 bzoj 1025 的弱化版.大概一样的 dp . 输出方案的时候小的环靠前.不用担心 dp 时用 > 还是 >= 来转 ...

  3. selenium - 截取页面图片和截取某个元素的图

    1.截取页面图片并保存 在测试过程中,是有必要截图,特别是遇到错误的时候进行截图. # coding:utf-8 from time import sleep from PIL import Imag ...

  4. STM32高级定时器用于普通定时,定时周期变长

    最近在用stm32定时器控制步进电机,由于普通定时器不够用,只能把TIM1当普通定时器用,我随手就把普通定时器的代码搬过去. void cs_Timer_Init(void) //TIM1 us级 { ...

  5. (转)使用PowerDesigner生成HTML功能

    本文转载自:http://www.cnblogs.com/CowboyProgrammer/archive/2009/04/28/1445423.html 使用PowerDesigner设计数据库关系 ...

  6. java数字游戏基础篇

    题目: 1.100以内,程序先产生一个随机数,然后用户从控制台输入数字,猜是大了还是小了,第7次时 输出 “您太笨了,答案是”+x 思路:1.随机数,所以用到random 2.用户从键盘输入 ,则用到 ...

  7. Oracle里的执行计划

    1 执行计划的查看 1 explan plan 2 dbms_xplan包 3 sqlplus中 set autot 4 10046 5 awr报告 6一些现成的脚本 7 10053 常见的就前4种 ...

  8. CP干货:手机游戏上线前需要准备什么

    转自:http://www.gamelook.com.cn/2015/09/229002 游戏研发完成后游戏该怎样推广?如何找渠道?推广时需要注意什么?下面给大家介绍一下具体流程,可能每个公司的上线流 ...

  9. 使用ResultSet结果集查询数据

    直接上下代码: package com.learn.jdbc.chap05; import java.sql.Connection; import java.sql.PreparedStatement ...

  10. 服务器实现处理GET和POST

    import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.Inp ...