이 질문은 C# MVC2 Jqgrid - what is the correct way to do server side paging?과 관련된 질문이며 2000 또는 그 이상의 행이있는 테이블의 쿼리 성능을 향상시키는 방법을 찾았습니다. 성능은 10 초에서 1 초로 향상되었습니다.C# Entity Framework + Linq - 어떻게 느린 쿼리를 빠르게 할 수 있습니까?
이제 테이블에 20,000 개의 행이 있고 쿼리에 30 초가 걸리는 정확한 쿼리를 수행하려고합니다. 어떻게하면 더 향상시킬 수 있습니까? 20,000 개의 행은 여전히 큰 숫자가 아닙니다.
몇 가지 가능한 아이디어 I는 한 :
조인 제거 드 정상화 향상 및- 대신 테이블
- 돈을 조회 및 가입 전체 테이블을 쿼리하지 말고 사용자가 일부 필터를 먼저 선택하도록하십시오 (예 : A | B | C .. 등 필터)
- 테이블에 인덱스를 더 추가하십시오.
- 다른 것?
이
public ActionResult GetProductList(int page, int rows, string sidx, string sord,
string searchOper, string searchField, string searchString)
{
if (sidx == "Id") { sidx = "ProductCode"; }
var pagedData = _productService.GetPaged(sidx, sord, page, rows);
var model = (from p in pagedData.Page<Product>()
select new
{
p.Id, p.ProductCode, p.ProductDescription,
Barcode = p.Barcode ?? string.Empty,
UnitOfMeasure = p.UnitOfMeasure != null ? p.UnitOfMeasure.Name : "",
p.PackSize,
AllocatedQty = p.WarehouseProducts.Sum(wp => wp.AllocatedQuantity),
QtyOnHand = p.WarehouseProducts.Sum(wp => wp.OnHandQuantity)
});
var jsonData = new
{
Total = pagedData.TotalPages, Page = pagedData.PageNumber,
Records = pagedData.RecordCount, Rows = model
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
ProductService 토륨 수 -
에게public ListPage GetPaged(string sidx, string sord, int page, int rows)
{
var list = GetQuery().OrderBy(sidx + " " + sord);
int totalRecords = list.Count();
var listPage = new ListPage
{
TotalPages = (totalRecords + rows - 1)/rows,
PageNumber = page,
RecordCount = totalRecords,
};
listPage.SetPageData(list
.Skip((page > 0 ? page - 1 : 0) * rows)
.Take(rows).AsQueryable());
return listPage;
}
내가 대신 조건의 문자열에 전달할 수 있도록 .OrderBy() 절은 LinqExtensions를 사용하는이 : .GetPaged()이가하는 genericRepository.GetPaged을 (호출 ProductRepository.GetPaged)를 호출 그것을 느리게하고 있습니까?
그리고 마지막으로 ListPage 편리 페이징에 대한 요구에있는 jqGrid 속성 마무리를위한 단지 클래스 :
public class ListPage
{
private IQueryable _data;
public int TotalPages { get; set; }
public int PageNumber { get; set; }
public int RecordCount { get; set; }
public void SetPageData<T>(IQueryable<T> data)
{
_data = data;
}
public IQueryable<T> Page<T>()
{
return (IQueryable<T>)_data;
}
}
GetQuery는 다음과 같습니다
public IQueryable<T> GetQuery()
{
return ObjectSet.AsQueryable();
}
.OrderBy 방법은 다음 두 가지 방법으로 구성 관습은 :
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source,
string ordering, params object[] values)
{
return (IQueryable<T>)OrderBy((IQueryable)source, ordering, values);
}
public static IQueryable OrderBy(this IQueryable source, string ordering,
params object[] values)
{
if (source == null) throw new ArgumentNullException("source");
if (ordering == null) throw new ArgumentNullException("ordering");
ParameterExpression[] parameters = new ParameterExpression[] {
Expression.Parameter(source.ElementType, "") };
ExpressionParser parser = new ExpressionParser(parameters, ordering, values);
IEnumerable<DynamicOrdering> orderings = parser.ParseOrdering();
Expression queryExpr = source.Expression;
string methodAsc = "OrderBy";
string methodDesc = "OrderByDescending";
foreach (DynamicOrdering o in orderings)
{
queryExpr = Expression.Call(
typeof(Queryable), o.Ascending ? methodAsc : methodDesc,
new Type[] { source.ElementType, o.Selector.Type },
queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters)));
methodAsc = "ThenBy";
methodDesc = "ThenByDescending";
}
return source.Provider.CreateQuery(queryExpr);
}
편집하면 genericBased 코드로 돌아갈 때 OrderBy가 비 generic 코드를 사용할 때 매우 혼란 스럽습니다 ... 명확하게 할 수 있습니까? 나는 명백한 것을 놓치고 있는가? –
죄송합니다. 당신이 무엇을 요구하는지 모르겠습니다 -이'OrderBy()'는 다른 클래스에 정의 된 확장 메소드입니다. –
글쎄,'GetQuery()'는'IQueryable'(generic)을 반환 할 것입니다; 'GetQuery(). 당신이 보여줄 방법을 사용하는 OrderBy (sidx + ""+ sord)'는'IQueryable' (non-generic)이 될 것이다. AFAIK는 비 제네릭에 대해 정의 된 * Skip (...) 등이 없습니다 ... 어떻게 작동 할 것인지 확실하지 않습니까? –