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