如何使我的Dynamic Linq查询更有效率

时间:2013-05-16 21:35:21

标签: performance linq-to-entities dynamic-linq asp.net-mvc-controller

我已经编写了一个mvc控制器函数来处理动态查询,它工作得很好,但是对于一些更复杂的查询,它实际上已经减少了15秒的响应时间。我使用ObjectQuery.ToTraceString获取sql并对我的数据库执行它,我得到1-2秒的响应时间,不是很好,但与我的服务器响应同一查询所花费的时间截然不同。

这是我的代码:

public class QueryController : Controller
{
    //
    // GET: /Query/
    Entities1 Context = new Entities1();
    public JsonResult Query(
        string select, 
        string table = "Product", 
        string where = "", 
        string groupBy = ""
        )
        IQueryable dataTable;
        if (table == "Customer") dataTable = Context.Customers;
        else if (table == "Product") dataTable = Context.Products;
        else if (table == "Purchase") dataTable = Context.Purchase;
        else dataTable = Context.Farms;

        if (select == null) return null;
        string whereClause = where;
        string selectClaus = select;
        string groupByClaus = groupBy;

        IQueryable queryResults = dataTable;
        if (where != "") queryResults = queryResults.Where(whereClause);
        if (groupByClaus != "") queryResults = queryResults.GroupBy(groupByClaus, "it");
        queryResults = queryResults.Select(selectClaus);

        JsonResult result = new JsonResult();
        result.Data = queryResults;
        result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        return result;
    }

}

此代码应该处理这样的请求:

 ?table=Purchase
 &select=new (Customer.First as Name, Product.Id as ProdId)
 &where=Category == 5

如上所述的查询大约需要700毫秒,但如果我尝试更复杂的东西,它会慢慢爬行(15秒):

?table=Purchase
&select=new (
    count(true) as Total,
    Key.Product as Product,
    Key.CustomerRef as CustomerRef,
    count(Price > 475) as BigPurchases,
    count(PaidFor == false)  as UnPaid,
    count((Category != null) and (Comments == null) and Returns == null) as NoFeedback)
&groupBy=new (
    Product.ProductName as Product,
    CustomerRef as CustomerRef
    )

特别是导航属性似乎是一个问题,删除它会大大加快查询速度(3秒):

?table=Purchase
&select=new (
    count(true) as Total,
    Key.Product as Product,
    Key.CustomerRef as CustomerRef,
    count(Price > 475) as BigPurchases,
    count(PaidFor == false)  as UnPaid,
    count((Category != null) and (Comments == null) and Returns == null) as NoFeedback)
&groupBy=new (
    ProductRef as Product,
    CustomerRef as CustomerRef
    )

所有似乎都被用来迭代IEnumerable的时间,在我提供的代码中我将数据传递出去,让任何底层的MVC代码做任何转换它想要的,这大约需要时间。但是,如果我自己迭代它,或者使用ToList函数,我会得到类似的慢响应时间。

有没有人对导致这些实体长时间停顿的原因有任何想法?

更新

我添加了索引到我的数据库,加快了速度,但是在linq中执行查询的时间仍然是在sql中执行的时间的20-30倍。

0 个答案:

没有答案