ASP.通过分页概念改进性能,我需要一个例子

  • 本文关键字:一个 分页 性能 ASP asp.net-mvc
  • 更新时间 :
  • 英文 :


我正在开发基于ASP的应用程序。并在MVC WebGrid中显示数据。

我使用LINQ从实体到EntityViewModel的记录。在这样做时,我必须将记录从实体转换为EntityViewModel。

我有30K记录要在网格中显示,对于每条记录都有3个标志,它必须去3个其他表,并比较记录的存在和绘画与真或假,并在网格中显示相同。

我一次显示10条记录,但它有点很慢,因为我要获取所有记录并存储在我的应用程序中。

分页已经到位(我的意思是说,只有10条记录显示在web网格中),但是所有的记录都被加载到应用程序中,这需要15-20秒。我已经检查了处理器花费这个时间的地方。它发生在绘制位置(其中每个记录都与其他3个表进行比较)。

我已经将LINQ查询转换为SQL,我可以看到我的SQL查询在2秒内执行。通过这个,我可以强烈地说,我不想把时间花在SQL索引上,因为SQL查询的速度已经足够好了。

我有两个选项要实现1)缓存MVC2)分页(我应该只得到前10条记录)。

我想使用分页技术来提高性能。

现在我的问题是我如何传递数字10(没有记录到服务方法),以便它只带来10条记录。以及如何在点击下一页时获得下一个10条记录。

我将发布代码,但我不能这样做,因为它有一些敏感数据。

如何处理这种情况的例子,非常感谢。

如果你使用SQL 2005 +,你可以在你的存储过程中使用ROW_NUMBER():

http://msdn.microsoft.com/en-us/library/ms186734 (v = SQL.90) . aspx

或者如果你只是想在LINQ中做,试试Skip()和Take()方法。

就像:

int page = 2;
int pageSize = 10; 
var pagedStuff = query.Skip((page - 1) * pageSize).Take(pageSize);

您应该始终,始终,始终限制从数据库中获取的行数。无界读取会杀死应用程序。30k变成了300k,你只是在破坏你的SQL服务器。

Jfar在. skip和. take上走对了路。Linq2Sql引擎(以及大多数实体框架)会将其转换为返回有限结果集的SQL。但是,这并不排除缓存结果。我也建议这样做。最快的SQL Server之旅是你不必走的。:)我做这样的事情,我的控制器方法处理页面或未页面的结果和缓存任何从SQL返回:

    [AcceptVerbs("GET")]
    [OutputCache(Duration = 360, VaryByParam = "*")]
    public ActionResult GetRecords(int? page, int? items)
    {
        int limit = items ?? defaultItemsPerPage;
        int pageNum = page ?? 0;
        if (pageNum <= 0) { pageNum = 1; }
        ViewBag.Paged = (page != null);
        var records = null;
        if (page != null)
        {
           records = myEntities.Skip((pageNum - 1) * limit).Take(limit).ToList();
        }
        else
        {
            records = myEntities.ToList();
        }
        return View("GetRecords", records);
    }

如果你调用它没有参数,你得到整个结果集(/GetRecords)。调用它将得到一个受限的集合(/GetRecords?page=3&items=25)。

你可以通过添加。contains和。startswith功能来进一步扩展这个方法。

如果您决定采用自定义存储过程路线,我建议使用"TOP"one_answers"ROW_NUMBER"来限制结果,而不是使用临时表。

我个人会创建一个自定义存储过程来完成这个任务,然后通过Linq to SQL调用它。例如

CREATE PROCEDURE [dbo].[SearchData]
(
@SearchStr NVARCHAR(50),
@Page int = 1,
@RecsPerPage int = 50,
@rc int OUTPUT
)
AS
SET NOCOUNT ON
SET FMTONLY OFF
DECLARE @TempFound TABLE
(
UID int IDENTITY NOT NULL,
PersonId UNIQUEIDENTIFIER
)
INSERT  INTO @TempFound
(
PersonId
)
SELECT PersonId FROM People WHERE Surname Like '%' + SearchStr + '%'
SET @rc = @@ROWCOUNT
-- Calculate the final offset for paging --
DECLARE @FirstRec int, @LastRec int
SELECT @FirstRec = (@Page - 1) * @RecsPerPage
SELECT @LastRec = (@Page * @RecsPerPage + 1)

-- Final select --
SELECT p.* FROM People p INNER JOIN @TempFound tf
ON p.PersonId = tf.PersonId
WHERE (tf.UID > @FirstRec) AND (tf.UID < @LastRec)

@rc参数是找到的记录总数。

显然你必须为你自己的表建模,但它应该运行得非常快。

要在Linq To SQL中将其绑定到对象,您只需确保最终选择字段与要绑定到的对象的字段匹配。

最新更新