2011-06-09 66 views
0

期间,我有一个ASP:GridView控件中包含列表 数据源我添加自定义分页,使用过程中,当我使用过程中的MS服务器管理Asp.net(C#)自定义分页使用存储过程 - 差绩效分页

工作室其性能很快,只要我尝试在asp.net中,性能是可怕的在

分页。 第一步(gridview填充时)非常快,但是当我开始分页时,

表现杀死,我等待5-25秒传递到下一页。

亲爱的,我必须做些什么来解决这个问题,你会帮我吗?

该处是存储过程

CREATE PROCEDURE [sp_QS] 
@startRowIndex INT, 
@maximumRows INT, 
@afterWhere NVARCHAR(MAX), 
@sortBy NVARCHAR(MAX), 
@totalRows INT OUT 
AS 

SET NOCOUNT ON; 

DECLARE @P NVARCHAR(MAX), @Q1 NVARCHAR(MAX), @Q2 NVARCHAR(MAX) 
DECLARE @first_id INT 

SET @startRowIndex = (@startRowIndex - 1) * @maximumRows 

SET @Q1 = 'query part 1' 

SET @Q2 = 'query part 2' 

IF @startRowIndex = 0 
BEGIN 
SET @startRowIndex = 1 
END 

SET ROWCOUNT @startRowIndex 
SET @P = 'SET NOCOUNT ON;  DECLARE @out INT  SELECT @out = id FROM table1 ' + @Q2 + ' 

WHERE ' + @afterWhere + '  SELECT @out' 

IF OBJECT_ID('tempdb..#t1','u') IS NOT NULL 
BEGIN 
DROP TABLE #t1 
END 
CREATE TABLE #t1 (col INT) 
INSERT #t1 EXEC(@P) 
SELECT @first_id = col FROM #t1 
DROP TABLE #t1 

--SELECT @first_id AS FFFF --PRINT @first_id 

SET ROWCOUNT @maximumRows 
SET @P = 'SET NOCOUNT ON;' + 'SELECT ' + @Q1 + ' FROM table ' + @Q2 + ' WHERE (id >=' + 

CAST(@first_id AS NVARCHAR(60)) + ') AND (' + @afterWhere + ') ' + @sortBy 
EXEC(@P) 

SET ROWCOUNT 0 

-- GET THE TOTAL ROWS 
IF @startRowIndex = 1 
BEGIN 
SET @P = 'SET NOCOUNT ON;' + 'SELECT COUNT(id) FROM table1 ' + @Q2 + ' WHERE ' + 

@afterWhere 
IF OBJECT_ID('tempdb..#t2','u') IS NOT NULL 
BEGIN 
DROP TABLE #t2 
END 
CREATE TABLE #t2 (col INT) 
INSERT #t2 EXEC (@P) 
SELECT @totalRows = col FROM #t2 
DROP TABLE #t2 
SELECT @totalRows AS QueryResultRowCount 
END 

GO 

这里是ASP.NET中的代码(用C#)

private void BindData() 
{ 
    string connectionString = "Server=localhost;" + 
      "Database=Northwind;Trusted_Connection=true"; 
    SqlConnection myConnection = new SqlConnection(connectionString); 
    SqlCommand myCommand = new SqlCommand("usp_GetProducts", 
              myConnection); 
    myCommand.CommandType = CommandType.StoredProcedure; 

    myCommand.Parameters.AddWithValue("@startRowIndex", 
             currentPageNumber); 
    myCommand.Parameters.AddWithValue("@maximumRows", PAGE_SIZE); 
    myCommand.Parameters.Add("@totalRows", SqlDbType.Int, 4); 
    myCommand.Parameters["@totalRows"].Direction = 
         ParameterDirection.Output; 

    SqlDataReader sqlReader = myCommand.ExecuteReader(); 

    while(sqlReader.Read()) 
    { 
     // filling List<> object to bind to gridview as datasource 
    } 
... 
} 

我不得不按钮 '下一个' 和 'prvious',按下这些按钮,我正在改变

currentPageNumber用+或 - 1,后面调用BindData()方法。

在此先感谢

+1

你运行通过SQL调优顾问存储过程SQL?很多次执行不当的sql语句通过仅添加其他索引或更新Sql Tuning Adviser可为您提供的统计信息得到解决。 – 2011-06-09 19:19:16

+0

使用CTE代替临时表http://blogs.x2line.com/al/archive/2005/11/18/1323.aspx – 2011-06-09 19:46:40

回答

0

这是从SQL Server 2005米的样品对AdventureWorks数据库的SQL:

DECLARE 
    @FirstRow int, 
    @LastRow int, 
    @Sorting varchar(50); 

Declare @SelectClause nvarchar(max), 
     @Params nvarchar(MAX); 

SELECT @FirstRow = 1, @LastRow = 10; 

SELECT @SelectClause = 'WITH CTE AS (
SELECT 
    ROW_NUMBER() OVER (ORDER BY ' + COALESCE(@Sorting, 'SalesOrderID ASC') + ') AS RowNumber, 
    COUNT(*) OVER() AS TotalRows, 
    SalesOrderID, 
    OrderDate, 
    DueDate, 
    CASE OnlineOrderFlag WHEN 1 THEN ''Yes'' ELSE ''No'' END as OnlineOrderFlagString 
FROM 
    Sales.SalesOrderHeader 
WHERE 
    SubTotal > 100) 

SELECT * FROM CTE WHERE RowNumber >= @FirstRow AND RowNumber < @LastRow', 
@Params = '@FirstRow int, @LastRow int'; 

exec sp_executesql 
    @statement = @SelectClause, 
    @params = @Params, 
    @FirstRow = @FirstRow, 
    @LastRow = @LastRow; 

后,您必须执行查询,你可以从第一行是否存在获取总价值的行。请注意,如果你必须提供像OnlineOrderFlagString计算列进行排序能力,查询会变得有点复杂:

DECLARE 
    @FirstRow int, 
    @LastRow int, 
    @Sorting varchar(50); 

Declare @SelectClause nvarchar(max), 
     @Params nvarchar(MAX); 

SELECT @FirstRow = 1, @LastRow = 10, @Sorting = 'OnlineOrderFlagString ASC' 

SELECT @SelectClause = 'WITH CTE_1 AS (
SELECT 
    SalesOrderID, 
    OrderDate, 
    DueDate, 
    CASE OnlineOrderFlag WHEN 1 THEN ''Yes'' ELSE ''No'' END as OnlineOrderFlagString 
FROM 
    Sales.SalesOrderHeader 
WHERE 
    SubTotal > 100), 
CTE_2 AS (
SELECT 
    ROW_NUMBER() OVER (ORDER BY ' + COALESCE(@Sorting, 'SalesOrderID ASC') + ') AS RowNumber, 
    COUNT(*) OVER() AS TotalRows, 
    SalesOrderID, 
    OrderDate, 
    DueDate, 
    OnlineOrderFlagString 
FROM 
    CTE_1 
) 

SELECT * FROM CTE_2 WHERE RowNumber >= @FirstRow AND RowNumber < @LastRow', 
@Params = '@FirstRow int, @LastRow int'; 

exec sp_executesql 
    @statement = @SelectClause, 
    @params = @Params, 
    @FirstRow = @FirstRow, 
    @LastRow = @LastRow;