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