以下是别人的说法:SQL Server 2005之后,令人困扰的分页问题似乎有了进展,那就是用ROW_NUMBER(),典型的语句如下SELECT *
FROM
(
SELECT *,ROW_NUMBER() OVER (ORDER BY XXX) AS RowNo
FROM tbl
) AS A
WHERE RowNo >= 11 and RowNo <= 20;
但这里忽略了一个重要的问题,那就是中间那个SELECT语句,实际上相当于做了一个SELECT *,虽然没在结果集看到,但没看到不表示数据库没做。
为什么看起来查询很快,其实是因为后面的RowNo的范围,网上流传的示例RowNo都较小,所以看不出问题,在上例中,SQL Server发现后面的条件之后,中间的SELECT被作了类似TOP 20的处理,也就是只取了20行,所以查询非常快。但把RowNo的查询范围改为10000000到1000010之后,则相当于先TOP 10万行,这时速度就明显慢下来了。
所以说,这个表达式的本质只是先TOP X,再选出X-y,X这个小范围的行,相比以前并没有什么进步。
我想问的是,ROW_NUMBER() 真的性能不那么好吗?ROW_NUMBER()是不是用到了临时表?
FROM
(
SELECT *,ROW_NUMBER() OVER (ORDER BY XXX) AS RowNo
FROM tbl
) AS A
WHERE RowNo >= 11 and RowNo <= 20;
但这里忽略了一个重要的问题,那就是中间那个SELECT语句,实际上相当于做了一个SELECT *,虽然没在结果集看到,但没看到不表示数据库没做。
为什么看起来查询很快,其实是因为后面的RowNo的范围,网上流传的示例RowNo都较小,所以看不出问题,在上例中,SQL Server发现后面的条件之后,中间的SELECT被作了类似TOP 20的处理,也就是只取了20行,所以查询非常快。但把RowNo的查询范围改为10000000到1000010之后,则相当于先TOP 10万行,这时速度就明显慢下来了。
所以说,这个表达式的本质只是先TOP X,再选出X-y,X这个小范围的行,相比以前并没有什么进步。
我想问的是,ROW_NUMBER() 真的性能不那么好吗?ROW_NUMBER()是不是用到了临时表?
解决方案 »
- SQL 批量 数据更新问题???
- 求解释语句。
- |zyciis| 400分求: 急大家来帮我看看我的分页存储过程:当为非主键分页的时候当第二页的时候就出错 大家帮分析一下看哪里出错 谢谢
- CSDN公告:4月底将强制结帖
- SqlServer 2008安装问题
- 在ASP中链接SQL SERVER 2000时,竟然出现以下问题,求助!!!
- 存储过程的问题。
- Sqlserver 2000的.LDF好像是日志文件吧,对我没用,但空间要占一堆,可不可以屏蔽
- sql server中有象access中自动编号的数据类型吗?
- yangzi :关于job和dbms的帖子为什么都找不到了
- 重开贴:这个sql语句如何写
- 我希望得出关联度大于等于n的记录
select top m * from tablename where id not in (select top n id from tablename)2.
select top m * into 临时表(或表变量) from tablename order by columnname -- 将top m笔插入
set rowcount n
select * from 表变量 order by columnname desc3.
select top n * from
(select top m * from tablename order by columnname) a
order by columnname desc
4.如果tablename里没有其他identity列,那么:
select identity(int) id0,* into #temp from tablename取n到m条的语句为:
select * from #temp where id0 >=n and id0 <= m如果你在执行select identity(int) id0,* into #temp from tablename这条语句的时候报错,那是因为你的DB中间的select into/bulkcopy属性没有打开要先执行:
exec sp_dboption 你的DB名字,'select into/bulkcopy',true
5.如果表里有identity属性,那么简单:
select * from tablename where identitycol between n and m 如果是sql server 2005 可以这样写:
select top 20 * from T order col
except
select top 2 * from T order col
--------
我测试的结果是ROW_NUMBER()性能很好,分页的时候比用TOP或临时表快。
--适用于 SQL Server 2000/2005
SELECT TOP 页大小 *
FROM table1
WHERE id NOT IN
(
SELECT TOP 页大小*(页数-1) id FROM table1 ORDER BY id
)
ORDER BY id
--方法2:
--适用于 SQL Server 2000/2005
SELECT TOP 页大小 *
FROM table1
WHERE id >
(
SELECT ISNULL(MAX(id),0)
FROM
(
SELECT TOP 页大小*(页数-1) id FROM table1 ORDER BY id
) A
)
ORDER BY id
--方法3:
--适用于 SQL Server 2005
SELECT TOP 页大小 *
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY id) AS RowNumber,* FROM table1
) A
WHERE RowNumber > 页大小*(页数-1)
--方法四 适用于 SQL Server 2005
DECLARE @pagenum AS INT, @pagesize AS INT
SET @pagenum = 2
SET @pagesize = 3
SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY newsid DESC) AS rownum,
newsid, topic, ntime, hits
FROM news) AS D
WHERE rownum BETWEEN (@pagenum-1)*@pagesize+1 AND @pagenum*@pagesize
ORDER BY newsid DESC
说明,页大小:每页的行数;页数:第几页。使用时,请把“页大小”和“页大小*(页数-1)”替换成数字。
数据越往后就越慢,还是top的方法比较快
SELECT TOP 页大小 *
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY id) AS RowNumber,* FROM table1
) A
WHERE RowNumber > 页大小*(页数-1)试用结果:比top有很大性能提升,翻页到1万页(10万条)不再死掉,但4万页(40万)左右开始,照样经常死掉。
修改查询语句为如下形式,也是一样
SELECT TOP 页大小 *
FROM
(
SELECT top 页大小*(页数) ROW_NUMBER() OVER (ORDER BY id) AS RowNumber,* FROM table1
) A
WHERE RowNumber > 页大小*(页数-1)