Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#实体框架+;Linq-如何加速慢速查询?_C#_Linq_Performance_Asp.net Mvc 2_Jqgrid - Fatal编程技术网

C#实体框架+;Linq-如何加速慢速查询?

C#实体框架+;Linq-如何加速慢速查询?,c#,linq,performance,asp.net-mvc-2,jqgrid,C#,Linq,Performance,Asp.net Mvc 2,Jqgrid,这是一个与我所问的问题有关的问题,我发现了如何提高2000行左右表的查询性能。性能从10秒提高到1秒 现在,我尝试执行完全相同的查询,其中表有20000行,而查询需要30秒。我如何进一步改进它?2万排还不是一个很大的数字 我有一些可能的想法: 可以通过取消规范化以删除连接和和来改进它 创建一个视图和查询,而不是查询和联接表 不要查询整个表,让用户先选择一些过滤器(例如A | B | C..等过滤器) 向表中添加更多索引 还有别的吗 这是一个MVC操作,对于20000行需要30秒:(参数由jq

这是一个与我所问的问题有关的问题,我发现了如何提高2000行左右表的查询性能。性能从10秒提高到1秒

现在,我尝试执行完全相同的查询,其中表有20000行,而查询需要30秒。我如何进一步改进它?2万排还不是一个很大的数字

我有一些可能的想法:

  • 可以通过取消规范化以删除连接和和来改进它
  • 创建一个视图和查询,而不是查询和联接表
  • 不要查询整个表,让用户先选择一些过滤器(例如A | B | C..等过滤器)
  • 向表中添加更多索引
  • 还有别的吗
这是一个MVC操作,对于20000行需要30秒:(参数由jqgrid提供,其中sidx=哪个排序列,sord=排序顺序)

.OrderBy()子句使用LinqExtensions,这样我就可以传入一个字符串而不是谓词-这会减慢速度吗

最后,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;
    }
}
公共类列表页
{
私有IQueryable_数据;
公共整型TotalPages{get;set;}
公共整数页码{get;set;}
公共int记录计数{get;set;}
公共void SetPageData(IQueryable数据)
{
_数据=数据;
}
公共可查询页面()
{
返回(IQueryable)\u数据;
}
}
GetQuery是:

public IQueryable<T> GetQuery()
{
    return ObjectSet.AsQueryable();
}
public IQueryable GetQuery()
{
返回ObjectSet.AsQueryable();
}
custom.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);
}
公共静态IQueryable OrderBy(此IQueryable源,
字符串排序,参数对象[]值)
{
return(IQueryable)OrderBy((IQueryable)源、顺序、值);
}
公共静态IQueryable OrderBy(此IQueryable源,字符串排序,
参数对象[]值)
{
如果(source==null)抛出新的ArgumentNullException(“source”);
if(ordering==null)抛出新的ArgumentNullException(“ordering”);
ParameterExpression[]参数=新的ParameterExpression[]{
Expression.Parameter(source.ElementType,“”)};
ExpressionParser=新的ExpressionParser(参数、顺序、值);
IEnumerable orderings=parser.ParseOrdering();
表达式queryExpr=source.Expression;
string methodAsc=“OrderBy”;
string methodDesc=“OrderByDescending”;
foreach(订单中的动态记录)
{
queryExpr=Expression.Call(
typeof(可查询),o.升序?methodAsc:methodDesc,
新类型[]{source.ElementType,o.Selector.Type},
queryExpr,Expression.Quote(Expression.Lambda(o.Selector,parameters));
methodAsc=“ThenBy”;
methodDesc=“然后按降序”;
}
返回source.Provider.CreateQuery(queryExpr);
}

我关心的是:

.Take(rows).AsQueryable()

您需要添加
AsQueryable()
这一事实向我表明,它当前是
IEnumerable
,这意味着您可能在查询的错误端执行分页(通过网络带回太多数据)。如果没有
GetQuery()
和自定义的
OrderBy()
,就很难确定-但一如既往,首先要做的是通过跟踪分析查询。查看执行的查询和返回的数据。这可能很容易,但SQL跟踪可能就足够了。

+1-还有一个鲜为人知的
ObjectQuery
ext meth,名为
.ToTraceString()
,它显示了要执行的SQL查询。非常方便的日志记录。很抱歉我错过了,
GetQuery()
是一行:
returnobjectset.AsQueryable()。我将编辑并添加OrderBy()的代码-我不知道它的来源,可能在这里:linqextensions.codeplex.com/@JK-老实说,如果删除
.AsQueryable()
@JK-也许?@Marc Gravell-
ObjectQuery
实现
IQueryable
,您只需检查代码是否有效即可
ObjectQuery
是特定于EF的,因为他正在使用EF,所以他可以对
ObjectQuery
执行显式转换:
var trace=((ObjectQuery)query)。ToTraceString()
。他正在做
ObjectSet.AsQueryable()
。如果他没有执行
AsQueryable
,并且对
ObjectSet
执行了一些LINQ操作,那么结果将是一个
ObjectQuery
。我错了吗?对于编辑,我很困惑,当OrderBy使用非泛型代码时,它如何跳回基于泛型的代码。。。你能澄清一下吗?我是否遗漏了一些明显的内容?抱歉,我不确定您在问什么-此
OrderBy()
是另一个类中定义的扩展方法。那么,
GetQuery()
将返回
IQueryable
(通用)
GetQuery().OrderBy(sidx+“”+sord)
(使用您显示的方法)将是
IQueryable
(非泛型)。AFAIK没有为非泛型定义
Skip(…)
etc。。。不确定这将如何工作?这也是一个愚蠢的问题,但是否有一个为您尝试进行的排序定义的索引?这能像向数据库列添加索引一样简单吗?关于泛型与非泛型的比较,这是一个很好的问题。我不知道,但当我将鼠标悬停在.OrderBy上时,它说它是
(扩展名)IQuerable
,它还说
var list
IQuerable
。ProductCode列上没有索引-据我所知,nvarchar(500)对于索引来说太大了。
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);
}
.Take(rows).AsQueryable()