2011-10-10 3 views
0

ASP.NET MVC 3.0을 기반으로 작성된 애플리케이션에서 MVC WebGrid에 데이터를 표시하고 있습니다.ASP.NET MVC3 - 페이징 개념을 통한 성능 향상, 예제가 필요합니까?

레코드를 EntityViewModel로 가져 오기 위해 LINQ를 사용하고 있습니다. 이 작업에서 엔터티 레코드를 EntityViewModel로 변환해야합니다.

그리드에 표시 할 30K 레코드가 있습니다. 각각의 레코드마다 3 개의 다른 테이블로 이동해야하며, 레코드와 페인트의 존재를 true 또는 false로 비교하여 동일하게 표시해야합니다. 그리드.

한 번에 10 개의 레코드가 표시되지만 모든 레코드를 가져 와서 응용 프로그램에 저장하면 매우 느립니다.

페이징 위치에 있습니다. (단, 10 개의 레코드 만 웹 그리드에 표시됩니다.)하지만 모든 레코드가 15-20 초가 걸리는 응용 프로그램에로드되고 있습니다. 나는이 시간이 프로세서에 의해 소비되는 곳을 확인했다. 페인팅 장소 (모든 레코드가 3 개의 다른 테이블과 비교되는)에서 발생합니다.

LINQ 쿼리를 SQL로 변환했으며 SQL 쿼리가 2 초 미만으로 실행되는 것을 확인할 수 있습니다. 이것에 의해, 나는 SQL 질의의 속도가 충분히 빠르기 때문에 SQL 인덱싱에 시간을 낭비하고 싶지 않다고 강력하게 말할 수 있습니다.

구현할 두 가지 옵션이 있습니다. 1) MVC 용 캐싱 2) 페이징 (처음 10 개 레코드 만 가져 오기).

성능 향상을 위해 페이징 기술을 사용하고 싶습니다.

이제 내 질문은 10 개의 레코드 (서비스 메서드에 레코드 없음)를 전달하여 10 개의 레코드 만 가져 오는 방법입니다. 또한 다음 페이지를 클릭 할 때 다음 10 개의 레코드를 얻으려면 어떻게해야합니까?

코드를 게시 하겠지만 중요한 데이터가 있으므로 코드를 게시 할 수 없습니다.

모든 사례에서이 상황을 해결하는 방법에 대해 많은 감사드립니다.

+1

실제 답변을 얻으려면 어떤 종류의 코드를 게시해야합니다. 민감한 정보가 드러나지 않도록하려면 변수 및 열 이름을 변경하십시오. – Dave

답변

-1

개인적으로이 작업을 수행하고 Linq를 통해 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 매개 변수는 발견 된 레코드의 총 개수입니다.

당신은 분명히 자신의 테이블을 모델링해야하지만 SQL에 Linq에있는 객체에 바인딩하려면 .. 매우 빠른

를 실행해야합니다, 당신은 단지 마지막이 필드가 일치 선택 있는지 확인해야합니다 그것이 바인드되는 객체의 필드

0

으로 간단하게 :

int page = 2; 
int pageSize = 10; 

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

당신은 항상, 항상, 항상 데이터베이스에서 얻을 행의 양을 제한해야한다. 무제한 읽기는 응용 프로그램을 중지시킵니다. 30k가 300k가되면 SQL 서버가 파손됩니다.

0

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).

기능 및 .StartsWith 기능을 추가하여이 방법을 확장 할 수 있습니다.

사용자 지정 저장 프로 시저 경로를 선택하는 경우 "TOP"및 "ROW_NUMBER"를 사용하여 임시 테이블 대신 결과를 제한하는 것이 좋습니다.