Я не могу дать вам достаточно данных, чтобы воспроизвести ошибки, поэтому я собираюсь дать вам столько данных, сколько смогу.
У меня есть оператор выбора, выполняющийся из ядра 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);
Сам SQL-запрос, приостановленный на сервере MSSQL, становится:
(@__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 management studio.
Однако приложение C # испытывает тайм-аут.
Когда я использую внутренние инструменты на MSSQL, я вижу, что spid приостановлен и постоянно ожидает.
Однако причина, кажется, меняется. В начале это связано с IO_COMPLETION. Затем его SOS_YIELD_ ~ что-то и, наконец, PAGEIOLATCH_SH
Это окончательное состояние остается в
Я, по жизни, не могу понять, почему MSSQL может выполнить запрос без каких-либо проблем.
Но EF, похоже, не в состоянии использовать индексы. Или что-то еще, чего мне не хватает полностью.
У меня просто нет идей. Кто-нибудь может указать мне направление, которое может помочь?
Я пытался:
Запуск в Visual Stuido 2017. Запуск в режиме выпуска. Я попытался включить ленивый режим, и не использовать включает. Я попытался удалить ленивые грузы и включения, просто чтобы посмотреть, смогу ли я вернуть заказы.
Неа. Кажется, MSSQL отказывает EF Core в использовании индексов.
Дело в том, что запрос зависает только тогда, когда я предоставляю определенные параметры.
Остальные параметры работают просто отлично. В частности, если я предоставлю разные коды валют, это будет иметь значение для MSSQL, если запрос будет приостановлен или нет.
Я полностью перестроил индексы, необходимые для эффективного выполнения этого запроса в соответствии с планом выполнения в MSSQL management studio.
Любая дополнительная информация, которая может потребоваться, пожалуйста, дайте мне знать, и я посмотрю, что я могу сделать, в меру своих усилий.
ОБНОВЛЕНИЕ Фактический план выполнения:
ОБНОВЛЕНИЕ 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