1

我编写了一个 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 倍。

4

0 回答 0