求助:SQL SERVER ROW_Number() OVER()分页问题

freesky0904 2019-01-11 04:15:56
with
a as
(
select admin_name from Admin where Department = 2
),
b as
(
select ROW_NUMBER() OVER (ORDER BY ID desc) AS R1,ID ,ClassID, NewsTitle, Source, Editor, Hits, isLock, isRecyle, addTime
FROM News inner join a on Admin_Name=Editor
where IsRecyle=0 AND isLock=0
)
select * from b where R1 between 35000 and 35019


(20 行受影响)
表 'Worktable'。扫描计数 1,逻辑读取 197832 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Admin'。扫描计数 1,逻辑读取 7 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'News'。扫描计数 1,逻辑读取 91186 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

SQL Server 执行时间:
CPU 时间 = 374 毫秒,占用时间 = 373 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

这是一个分页查询,数据才11万,SQL2008数据库,想请教大家,Worktable逻辑读取这么多正常吗?语句有问题吗?如果要改,需要如何改进呢?求更好的查询方法。

另外,将此查询在SQL2005的数据库中使用,速度完全不一样。以下为SQL2005中查询:

(20 行受影响)
表 'Admin'。扫描计数 1,逻辑读取 1559480 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'News'。扫描计数 1,逻辑读取 40998 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

(1 行受影响)

SQL Server 执行时间:
CPU 时间 = 3495 毫秒,占用时间 = 3711 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
...全文
255 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
freesky0904 2019-01-14
  • 打赏
  • 举报
回复
搞明白了,原来是SQL2005里边没有走索引,用WITH(INDEX(索引名))强制走索引就行了,谢谢。。。
freesky0904 2019-01-14
  • 打赏
  • 举报
回复
引用 1 楼 吉普赛的歌 的回复:
--添加索引,单独执行
CREATE INDEX ix_Admin_Admin_Name_Department ON Admin(Admin_Name, Department);
CREATE INDEX ix_News_Editor ON News(Editor);


不要那么太多不必要的公共表表达式, 你看着是清楚了, 但执行计划可能受影响。
按下面的试下:
WITH b AS
(
SELECT ROW_NUMBER() OVER(ORDER BY ID DESC) AS R1,
ID,
ClassID,
NewsTitle,
Source,
Editor,
Hits,
isLock,
isRecyle,
addTime
FROM News
INNER JOIN Admin AS a
ON a.Admin_Name = Editor AND a.Department = 2
WHERE IsRecyle = 0
AND isLock = 0
)
SELECT *
FROM b
WHERE R1 BETWEEN 35000 AND 35019


不知道怎么回事,我在SQL2005里边,建的索引好像不起作用,而且用的是同样的代码,是数据库有问题吗?
这个用语句创建的索引和用软件直接创建的效果是一样的吧?
能否告知一下联系QQ呀,方便请教你。
吉普赛的歌 版主 2019-01-11
  • 打赏
  • 举报
回复
--添加索引,单独执行
CREATE INDEX ix_Admin_Admin_Name_Department ON Admin(Admin_Name, Department);
CREATE INDEX ix_News_Editor ON News(Editor);
不要那么太多不必要的公共表表达式, 你看着是清楚了, 但执行计划可能受影响。 按下面的试下:
WITH b AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY ID DESC) AS R1,
        ID,
        ClassID,
        NewsTitle,
        Source,
        Editor,
        Hits,
        isLock,
        isRecyle,
        addTime
    FROM   News
        INNER JOIN Admin AS a
                ON  a.Admin_Name = Editor AND a.Department = 2
    WHERE IsRecyle = 0
        AND isLock = 0
)
SELECT *
FROM   b
WHERE  R1 BETWEEN 35000 AND 35019

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧