我不能给你足够的数据来重现错误,所以我会尽可能多地给你数据。
我有一个从 EF 核心执行的选择语句。
var bookings = context.Booking
.Where(booking => booking.ConsigneeNumber == customer.GetCustomerTarget().Code
&& booking.CreatedAt >= from
&& booking.CreatedAt < to
&& booking.BookingLine.Any(b => b.BookingLineSpecification
.Any(c => c.CurrencyCode == code))
)
.Include(booking => booking.BookingLine)
.ThenInclude(bl => bl.BookingLineSpecification)
.ThenInclude(bls => bls.UnitType)
.Include(booking => booking.BookingLine)
.ThenInclude(bl => bl.BookingLineAddress)
.ThenInclude(bla => bla.Country)
.Include(booking => booking.BookingLine)
.ThenInclude(bl => bl.BookingLineAddress)
.ThenInclude(bla => bla.PostalCode)
.Include(booking => booking.BookingLine)
.ThenInclude(bl => bl.BookingLineSpecification)
.ThenInclude(bls => bls.RelBookingLineSpecificationSalesInvoiceDetail)
.ThenInclude(Rel => Rel.SalesInvoiceDetail);
在 MSSQL 服务器上挂起的 SQL 查询本身变为:
(@__GetCustomerTarget_Code_0 bigint,@__from_1 datetime2(7),@__to_2 datetime2(7),@__code_3 varchar(255))
SELECT [booking].[Id],
[booking].[booking_provider_id],
[booking].[booking_status_id],
[booking].[consignee_name],
[booking].[consignee_number],
[booking].[created_at],
[booking].[created_by],
[booking].[currency_code],
[booking].[deliveryNumber],
[booking].[description],
[booking].[destroyed_at],
[booking].[destroyed_by],
[booking].[inter_company_number],
[booking].[invoicee_name],
[booking].[invoicee_number],
[booking].[is_create],
[booking].[location_id],
[booking].[location_name],
[booking].[maturity_level_id],
[booking].[number],
[booking].[order_number],
[booking].[provider_key],
[booking].[shipment_id],
[booking].[system_responsible_id],
[booking].[updated_at],
[booking].[updated_by]
FROM [Integration].[booking] AS [booking]
WHERE ((([booking].[consignee_number] = @__GetCustomerTarget_Code_0)
AND ([booking].[created_at] >= @__from_1))
AND ([booking].[created_at] < @__to_2))
AND EXISTS (
SELECT 1
FROM [Integration].[booking_line] AS [b]
WHERE EXISTS (
SELECT 1
FROM [Integration].[booking_line_specification] AS [c]
WHERE ([c].[currency_code] = @__code_3) AND ([b].[Id] = [c].[booking_line_id])) AND ([booking].[Id] = [b].[booking_id]))
在 MSSQL 管理工作室中执行时,此语句在零秒(但几毫秒)内执行。但是,C# 应用程序遇到超时。
当我在 MSSQL 上使用内部工具时,我可以看到 spid 被挂起,并且永久等待。然而,原因似乎正在改变。一开始是由于IO_COMPLETION。然后它的 SOS_YIELD_~something 最后是 PAGEIOLATCH_SH 这个最终状态它停留在
我一生都无法弄清楚为什么 MSSQL 可以毫无问题地执行查询。但是 EF 似乎没有使用索引。或者我完全错过的其他东西。
我只是没有想法。谁能指出我可能有帮助的方向?
我试过了:
在 Visual stuido 2017 中运行它。在发布模式下运行。我试过启用惰性模式,而不是使用包含。我已经尝试删除延迟加载和包含,只是为了看看我是否可以恢复预订。
没有。MSSQL 似乎拒绝 EF Core 使用索引。
问题是,只有当我提供某些参数时,查询才会挂起。其他参数工作得很好。具体来说,如果我提供不同的货币代码,那么无论查询是否暂停,这似乎都会对 MSSQL 产生影响。
我已经根据 MSSQL 管理工作室中的执行计划完全重建了高效执行此查询所需的索引。
任何可能需要的进一步信息,请告诉我,我会尽我所能,看看我能做些什么。
UPDATE 实际执行计划:
更新 2:我想指出,这目前正在用于开发,因此这个数据库、我的软件以及介于两者之间的任何东西都在我的“控制”之下。
就我显然缺乏经验的头脑可以控制任何事情而言:)
因此,任何关于如何更好地调试问题的建议,或对更多数据的请求都将得到积极和赞赏。并且很可能是可能的,尤其是在暗示如何提供给您的情况下!(和我)
SQL Profiler:打开与数据库的连接:
set quoted_identifier on
set arithabort on
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed