У меня есть оператор выбора, выполняемый из ядра 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
WHERE EXISTS (
SELECT 1
FROM [Integration].[booking_line_specification] AS [c]
WHERE ([c].[currency_code] = @__code_3) AND (.[Id] = [c].[booking_line_id])) AND ([booking].[Id] = .[booking_id]))
Этот оператор выполняется за ноль секунд (но за несколько миллисекунд) при выполнении в студии управления MSSQL.
Однако приложение C# испытывает тайм-аут.
Когда я использую внутренние инструменты MSSQL, я вижу, что spid приостановлен и постоянно ожидает.
Однако причина, похоже, меняется. Вначале это связано с IO_COMPLETION. Затем это SOS_YIELD_~что-то и, наконец, PAGEIOLATCH_SH
Это окончательное состояние, в котором он остается
Я, хоть убей, не могу понять, почему MSSQL может выполнить запрос вообще без проблем.
Но EF, похоже, не может использовать индексы. Или что-то еще, что мне совсем не хватает.
У меня просто нет идей. Может ли кто-нибудь указать мне направление, которое может помочь?
Я пробовал:
Запустить его в Visual stuido 2017. Запустить в режиме выпуска. Я попробовал включить ленивый режим и не использовать включения. Я попытался удалить ленивые загрузки и включения, просто чтобы посмотреть, смогу ли я вернуть заказы.
Нет. MSSQL, похоже, отказывается EF Core от использования индексов.
Дело в том, что запрос зависает только тогда, когда я предоставляю определенные параметры.
Другие параметры работают нормально. В частности, если я предоставлю разные коды валют, это, похоже, будет иметь решающее значение для MSSQL, будет ли запрос приостановлен или нет.
Я полностью перестроил индексы, необходимые для эффективного выполнения этого запроса в соответствии с планом выполнения в студии управления MSSQL.
Любая дополнительная информация, которая может потребоваться, дайте мне знать, и я посмотрю, что я могу сделать, насколько смогу.
ОБНОВЛЕНИЕ Фактический план выполнения:

ОБНОВЛЕНИЕ 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
Подробнее здесь: https://stackoverflow.com/questions/541 ... ent-studio
Мобильная версия