mssql分頁存儲過程
1. 如果在資料庫中有大數據量,而我們用分頁存儲過程,怎麼樣才能效率高
--------------------------------
--關於分頁儲存的效率問題
--5個存儲過程都是採用不同的方式
--------------------------------
------------------------------------------
--利用select top 和select not in進行分頁--
------------------------------------------
create procere proc_paged_with_notin --利用select top and select not in
(
@pageIndex int, --頁索引
@pageSize int --每頁記錄數
)
as
begin
set nocount on;
declare @timediff datetime --耗時
declare @sql nvarchar(500)
select @timediff=Getdate()
set @sql='select top '+str(@pageSize)+' * from tb_TestTable where(ID not in(select top '+str(@pageSize*@pageIndex)+' id from tb_TestTable order by ID ASC)) order by ID'
execute(@sql) --因select top後不支技直接接參數,所以寫成了字元串@sql
select datediff(ms,@timediff,GetDate()) as 耗時
set nocount off;
endexec proc_paged_with_notin 10000,10
--------------------------------------
--利用select top 和 select max(列鍵)--
--------------------------------------
create procere proc_paged_with_selectMax --利用select top and select max(列)
(
@pageIndex int, --頁索引
@pageSize int --頁記錄數
)
as
begin
set nocount on;
declare @timediff datetime
declare @sql nvarchar(500)
select @timediff=Getdate()
set @sql='select top '+str(@pageSize)+' * From tb_TestTable where(ID>(select max(id) From (select top '+str(@pageSize*@pageIndex)+' id From tb_TestTable order by ID) as TempTable)) order by ID'
execute(@sql)
select datediff(ms,@timediff,GetDate()) as 耗時
set nocount off;
end--------------------------------------------------------
--利用select top和中間變數--此方法因網上有人說效果最佳--
--------------------------------------------------------
create procere proc_paged_with_Midvar --利用ID>最大ID值和中間變數
(
@pageIndex int,
@pageSize int
)
as
declare @count int
declare @ID int
declare @timediff datetime
declare @sql nvarchar(500)
begin
set nocount on;
select @count=0,@ID=0,@timediff=getdate()
select @count=@count+1,@ID=case when @count<=@pageSize*@pageIndex then ID else @ID end from tb_testTable order by id
set @sql='select top '+str(@pageSize)+' * from tb_testTable where ID>'+str(@ID)
execute(@sql)
select datediff(ms,@timediff,getdate()) as 耗時
set nocount off;
end
---------------------------------------------------------------------------------------
--利用Row_number() 此方法為SQL server 2005中新的方法,利用Row_number()給數據行加上索引--
---------------------------------------------------------------------------------------
create procere proc_paged_with_Rownumber --利用SQL 2005中的Row_number()
(
@pageIndex int,
@pageSize int
)
as
declare @timediff datetime
begin
set nocount on;
select @timediff=getdate()
select * from (select *,Row_number() over(order by ID asc) as IDRank from tb_testTable) as IDWithRowNumber where IDRank>@pageSize*@pageIndex and IDRank<@pageSize*(@pageIndex+1)
select datediff(ms,@timediff,getdate()) as 耗時
set nocount off;
end
--------------------------
--利用臨時表及Row_number--
--------------------------
create procere proc_CTE --利用臨時表及Row_number
(
@pageIndex int, --頁索引
@pageSize int --頁記錄數
)
as
set nocount on;
declare @ctestr nvarchar(400)
declare @strSql nvarchar(400)
declare @datediff datetime
begin
select @datediff=GetDate()
set @ctestr='with Table_CTE as
(select ceiling((Row_number() over(order by ID ASC))/'+str(@pageSize)+') as page_num,* from tb_TestTable)';
set @strSql=@ctestr+' select * From Table_CTE where page_num='+str(@pageIndex)
end
begin
execute sp_executesql @strSql
select datediff(ms,@datediff,GetDate())
set nocount off;
end
我們分別在每頁10條數據的情況下在第2頁,第1000頁,第10000頁,第100000頁,第199999頁進行測試,耗時單位:ms 每頁測試5次取其平均值 存過第2頁耗時第1000頁耗時第10000頁耗時第100000頁耗時第199999頁耗時效率排行1用not in0ms16ms47ms475ms953ms32用select max5ms16ms35ms325ms623ms13中間變數_number0ms0ms34ms365ms710ms24臨時表780ms796ms798ms780ms805ms4正好我正在研究這個問題 給大家分享
2. SQLSERVER如何實現分頁查詢
寫存儲過程 ..
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
ALTER PROCEDURE usp_Province_pagination
@PageSize INT, --每頁的顯示的行數
@AbsolutePage INT, -- 當前頁的頁數
@PageCount INT OUTPUT --總頁數
AS
DECLARE @BeginRecord INT --記錄每此從哪一行開始讀取
DECLARE @RecordCount INT --表中數據的總條數
DECLARE @sql NVARCHAR(1000)
SET @RecordCount = (SELECT count(*) FROM Province)
--表中沒有數據的情況
IF @RecordCount = 0
BEGIN
SET @PageCount = 0
RETURN(0)
END
-- 表中的總條數大於定義的每頁的行數的情況
IF @RecordCount > @PageSize
BEGIN
-- 計算總能分多少頁
SET @PageCount = (@RecordCount + @PageSize - 1)/@PageSize
--當前應該從哪一行開始讀取
SET @BeginRecord = ((@AbsolutePage-1) * @PageSize)
SET @sql = N'SELECT TOP ' + cast(@PageSize AS NVARCHAR(100)) +' ProvinceID, provinceCode, ProvinceName
FROM Province
WHERE ProvinceID NOT IN
(SELECT TOP '+ CAST(@BeginRecord AS NVARCHAR(100)) + ' ProvinceID
FROM Province)'
EXECUTE sp_executesql @sql
END
ELSE -- -- 表中的總條數大於定義的每頁的行數情況
BEGIN
SET @PageCount = 1
SET @SQL = 'SELECT ProvinceID, provinceCode, ProvinceName FROM Province '
EXECUTE sp_executesql @sql
END
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
3. Sql server2008怎樣分頁
你可以用存儲過程分頁,如下存儲過程支持分頁和排序:
CREATE PROCEDURE GetSortedMovies
(
@SortExpression NVarChar(100),
@StartRowIndex INT,
@MaximumRows INT
)
AS
-- 創建一個臨時表存儲查詢結果
CREATE TABLE #PageIndex
(
IndexId INT IDENTITY (1,1) NOT NULL,
RecordId INT
)
-- 插入臨時表
INSERT INTO #PageIndex (RecordId)
SELECT Id FROM Movies
ORDER BY
CASE WHEN @SortExpression='Id' THEN Id END ASC,
CASE WHEN @SortExpression='Id DESC' THEN Id END DESC,
CASE WHEN @SortExpression='Title' THEN Title END ASC,
CASE WHEN @SortExpression='Title DESC' THEN Title END DESC,
CASE WHEN @SortExpression='Description' THEN Description END ASC,
CASE WHEN @SortExpression='Description DESC' THen Description END DESC
-- 得到頁數
SELECT Id,Title,Description FROM Movies
INNER JOIN #PageIndex WITH (nolock)
ON Movies.Id = #PageIndex.RecordId
WHERE #PageIndex.IndexId > @StartRowIndex
AND #PageIndex.IndexId < (@StartRowIndex + @MaximunRows + 1)
ORDER BY #PageIndex.IndexId
4. SQL如何實現數據分頁,要具體語句,謝謝
可以的,用存儲過程
分頁存儲過程如下
CREATE PROCEDURE GetRecordFromPage
@tblName varchar(255), -- 表名
@RetColumns varchar(1000) = '*', -- 需要返回的列,默認為全部
@Orderfld varchar(255), -- 排序欄位名
@PageSize int = 10, -- 頁尺寸
@PageIndex int = 1, -- 頁碼
@IsCount bit = 0, -- 返回記錄總數, 非 0 值則返回
@OrderType varchar(50) = 'asc', -- 設置排序類型, 非 asc 值則降序
@strWhere varchar(1000) = '' -- 查詢條件 (注意: 不要加 where)
AS
declare @strSQL varchar(1000) -- 主語句
declare @strTmp varchar(300) -- 臨時變數
declare @strOrder varchar(400) -- 排序類型
if @IsCount != 0 --執行總數統計
begin
if @strWhere != ''
set @strSQL = "select count(*) as Total from [" + @tblName + "] where " + @strWhere
else
set @strSQL = "select count(*) as Total from [" + @tblName + "]"
end
else --執行查詢操作
begin
if @OrderType != 'asc'
begin
set @strTmp = "<(select min"
set @strOrder = " order by [" + @Orderfld +"] desc"
end
else
begin
set @strTmp = ">(select max"
set @strOrder = " order by [" + @Orderfld +"] asc"
end
set @strSQL = "select top " + str(@PageSize) + " " + @RetColumns + " from ["
+ @tblName + "] where [" + @Orderfld + "]" + @strTmp + "(["
+ @Orderfld + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
+ @Orderfld + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)"
+ @strOrder
if @strWhere != ''
set @strSQL = "select top " + str(@PageSize) + " " + @RetColumns + " from ["
+ @tblName + "] where [" + @Orderfld + "]" + @strTmp + "(["
+ @Orderfld + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
+ @Orderfld + "] from [" + @tblName + "] where (" + @strWhere + ") "
+ @strOrder + ") as tblTmp) and (" + @strWhere + ") " + @strOrder
if @PageIndex = 1
begin
set @strTmp = ""
if @strWhere != ''
set @strTmp = " where (" + @strWhere + ")"
set @strSQL = "select top " + str(@PageSize) + " " + @RetColumns + " from ["
+ @tblName + "]" + @strTmp + " " + @strOrder
end
end
exec (@strSQL)
5. 在SQL中存儲過程的一般語法是什麼
1、 創建語法
createproc|procerepro_name
[{@參數數據類型}[=默認值][output],
{@參數數據類型}[=默認值][output],
....
]
as
SQL_statements
2、 創建不帶參數存儲過程
--創建存儲過程
if(exists(select*fromsys.objectswherename='proc_get_student'))
dropprocproc_get_student
go
createprocproc_get_student
as
select*fromstudent;
--調用、執行存儲過程
execproc_get_student;
3、 修改存儲過程
--修改存儲過程
alterprocproc_get_student
as
select*fromstudent;
4、 帶參存儲過程
--帶參存儲過程
if(object_id('proc_find_stu','P')isnotnull)
dropprocproc_find_stu
go
createprocproc_find_stu(@startIdint,@endIdint)
as
select*fromstudentwhereidbetween@startIdand@endId
go
execproc_find_stu2,4;
5、 帶通配符參數存儲過程
--帶通配符參數存儲過程
if(object_id('proc_findStudentByName','P')isnotnull)
dropprocproc_findStudentByName
go
createprocproc_findStudentByName(@namevarchar(20)='%j%',@nextNamevarchar(20)='%')
as
select*fromstudentwherenamelike@nameandnamelike@nextName;
go
execproc_findStudentByName;execproc_findStudentByName'%o%','t%';
(5)mssql分頁存儲過程擴展閱讀:
SQL存儲過程優點:
1、重復使用。存儲過程可以重復使用,從而可以減少資料庫開發人員的工作量。
2、減少網路流量。存儲過程位於伺服器上,調用的時候只需要傳遞存儲過程的名稱以及參數就可以了,因此降低了網路傳輸的數據量。
3、安全性。參數化的存儲過程可以防止SQL注入式攻擊,而且可以將Grant、Deny以及Revoke許可權應用於存儲過程。