zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

sqlserver关于分页存储过程的优化【让数据库按我们的意思执行查询计划】

SQLServer数据库存储执行 查询 优化 过程 关于
2023-06-13 09:14:30 时间
复制代码代码如下:

--代码一DECLARE@ccINT
SELECTNewsId,ROW_NUMBER()OVER(ORDERBYSortNumDESC)ASRowIndexINTO#tbFROMnewsWITH(NOLOCK)WHERENewsTypeId=@NewsTypeIdANDIsShow=1
SET@cc=@@ROWCOUNT
SELECTn.*FROMnewsASnWITH(NOLOCK),#tbAstWHEREt.RowIndex>@PageIndex*@PageSizeANDt.RowIndex<=(@PageIndex+1)*@PageSizeANDt.newsid=n.newsid
SELECT@cc
DROPTABLE#tb

复制代码代码如下:

--代码二
DECLARE@ccINT
SELECTNewsId,ROW_NUMBER()OVER(ORDERBYSortNumDESC)ASRowIndexINTO#tbFROMnewsWITH(NOLOCK)WHERENewsTypeId=@NewsTypeIdANDIsShow=1
SET@cc=@@ROWCOUNT
SELECTNewsIdINTO#tb2FROM#tbAstWHEREt.RowIndex>@PageIndex*@PageSizeANDt.RowIndex<=(@PageIndex+1)*@PageSize
SELECT*FROMnewsWITH(NOLOCK)WHERENewsIdIN(SELECT*FROM#tb2)
SELECT@cc
DROPTABLE#tb
DROPTABLE#tb2

答案是代码二远远高于代码一。在代码一中加粗代码的操作会引起整表扫描,因为数据库引擎在认为WHERE表达式中满足条件记录大于一定阀值的时候,就不再去进行查询优化,而直接使用表扫描。看执行信息,:
表"news"。扫描计数1,逻辑读取342次,物理读取0次,预读0次,lob逻辑读取0次,lob物理读取0次,lob预读0次。
(98361行受影响)
(1行受影响)
(40行受影响)
表"#tb________________________________________00000004C024"。扫描计数1,逻辑读取257次,物理读取0次,预读0次,lob逻辑读取0次,lob物理读取0次,lob预读0次。
表"news"。扫描计数1,逻辑读取2805次,物理读取0次,预读235次,lob逻辑读取0次,lob物理读取0次,lob预读0次。
(1行受影响)
(1行受影响)

原本,我想的执行计划,加粗部分的代码应该是聚焦索引查找,这样性能就提高很多。看代码二:
表"news"。扫描计数1,逻辑读取342次,物理读取0次,预读0次,lob逻辑读取0次,lob物理读取0次,lob预读0次。
(98361行受影响)
(1行受影响)
表"#tb____________________________________00000004BEEF"。扫描计数1,逻辑读取257次,物理读取0次,预读0次,lob逻辑读取0次,lob物理读取0次,lob预读0次。
(40行受影响)
(1行受影响)
(40行受影响)
表"news"。扫描计数0,逻辑读取131次,物理读取0次,预读0次,lob逻辑读取0次,lob物理读取0次,lob预读0次。
表"#tb2___________________________________00000004BEF0"。扫描计数1,逻辑读取2次,物理读取0次,预读0次,lob逻辑读取0次,lob物理读取0次,lob预读0次。
(1行受影响)
(1行受影响)

很明显,代码二与代码一中的IO操作数大大降低。且代码一随着@PageIndex越来越大,效率会越来越低;但代码二的效率不会随@PageIndex变化而改变。