我有一个报告,显示了一个确定的商家订单,并且它工作正常,直到我需要添加一个过滤器的付款状态。优化LINQ查询
这是我如何通过过滤器生成查询,过滤器:
var queryOrder = context.Orders.Select(m=>m);
if (viewModel.InitialDate.HasValue)
queryOrder = queryOrder.Where(m => m.CreatedDate.Date >= viewModel.InitialDate.Value);
(...) /* continues building the query, filter by filter */
if (viewModel.SelectedPaymentStatus != null)
queryOrder = queryOrder.Where(m => viewModel.SelectedPaymentStatus.Contains(m.Payments.Select(p => p.PaymentStatusId).Single().ToString()));
queryOrder = queryOrder.Where(m => m.MerchantId == merchantId);
当我运行queryOrder
,哪怕它只是一个queryOrder.Count()
,它需要1分钟来执行。使用SQL Server的性能分析工具,我提取生成的查询是这样的:
SELECT [t0].[Id], [t0].[CustomerId], [t0].[MerchantId], [t0].[OrderNumber], [t0].[Amount], [t0].[SoftDescriptor], [t0].[ShippingMethod], [t0].[ShippingPrice], [t0].[IpAddress], [t0].[SellerComment], [t0].[CreatedDate]
FROM [dbo].[Order] AS [t0]
WHERE ([t0].[MerchantId] = @p0)
AND ((CONVERT(NVarChar,(
SELECT [t1].[PaymentStatusId]
FROM [dbo].[Payment] AS [t1]
WHERE [t1].[OrderId] = [t0].[Id]
))) IN (@p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8))
的@ P0参数是MERCHANTID一个GUID和@ P1直通@ P8是数字串"1"
通"8"
,代表paymentStatusId的。
如果我跳过行:
if (viewModel.SelectedPaymentStatus != null)
queryOrder = queryOrder.Where(m => viewModel.SelectedPaymentStatus.Contains(m.Payments.Select(p => p.PaymentStatusId).Single().ToString()));
查询运行在不到1秒钟。但是当我使用它时,表演击中了地板。有关如何解决此问题的任何提示?
你说的生成的SQL运行速度更快? – 2013-03-21 14:50:34
和这个实体框架或LINQ到SQL? – 2013-03-21 14:52:09
不,即使在sql管理工作室中,生成的sql运行速度也很慢。这是LINQ to sql – leobelones 2013-03-21 14:54:59