Медленный запрос EF 4 с включением и объединениями - PullRequest
1 голос
/ 29 мая 2020

У меня следующий запрос EF 4, который занимает от 7 до 8 минут.

List<SecureDevice> tempSecureDevices = objectContext.SecureDevices.Select(x => new
            {
                SecureDevice = x,
                SecureDeviceCommands = objectContext.SecureDeviceCommands.Where(sdc => sdc.SecureDeviceKey == x.Key)
            }).SelectMany(x => x.SecureDeviceCommands.DefaultIfEmpty(), (x, r) => new { SecureDevice = x.SecureDevice, SecureDeviceCommand = r })
                .Select(x => new
                {
                    Data = x,
                    IsmConfigurationSecurityKeys = objectContext.IsmConfigurationSecurityKeys.Where(icsk => icsk.SecureDeviceKey == x.SecureDevice.Key)
                }).SelectMany(x => x.IsmConfigurationSecurityKeys.DefaultIfEmpty(), (x, r) => new { SecureDevice = x.Data.SecureDevice, SecureDeviceCommand = x.Data.SecureDeviceCommand, IsmConfigurationSecurityKey = r })
                .Where(x => secureDeviceInfoIds.Contains(x.SecureDevice.DeviceId))
                .AsEnumerable() //AsEnumerable executes the query.
                .Select(x => x.SecureDevice).Distinct().ToList();

Таблица SecureDeviceCommand здесь самая большая. содержит около 39000 записей.

Нам нужны объединения, поскольку они важны. Я попытался материализовать это как

tempSecureDevices = objectContext.SecureDevices.Where(x => secureDeviceInfoIds.Contains(x.DeviceId)).Include("SecureDeviceCommands").ToList();

Это заняло еще больше времени. Я новичок в EF. Я понимаю, что одной из причин могла быть старая версия EF. Я имею в виду, что более новый может быть быстрее.

Ran SQL профилировщик, и ниже был упомянут сгенерированный запрос. Я не мог найти способ улучшить это. Я потратил на это много времени. Я был бы очень признателен за помощь.

SELECT 
[Extent1].[DeviceType] AS [DeviceType], 
[Extent1].[Key] AS [Key], 
[Extent1].[DeviceId] AS [DeviceId], 
[Extent1].[IsmDeviceStatus] AS [IsmDeviceStatus], 
[Extent1].[Revision] AS [Revision], 
[Extent1].[ChangeSetKey] AS [ChangeSetKey], 
[Extent1].[IsmCurrentSecurityLevel] AS [IsmCurrentSecurityLevel], 
[Extent1].[IsmPendingSecurityLevel] AS [IsmPendingSecurityLevel], 
[Extent1].[NextTrackingId] AS [NextTrackingId], 
[Extent1].[IsmAsOfDateTime] AS [IsmAsOfDateTime], 
[Extent1].[FdmExpectedSecurityState] AS [FdmExpectedSecurityState], 
[Extent1].[FdmCurrentSecurityState] AS [FdmCurrentSecurityState], 
[Extent1].[BusinessUnitKey] AS [BusinessUnitKey], 
[Extent1].[DeviceMode] AS [DeviceMode], 
[Extent2].[Key] AS [Key1], 
[Extent2].[SecureDeviceKey] AS [SecureDeviceKey], 
[Extent2].[IsmConfigurationKey] AS [IsmConfigurationKey], 
[Extent2].[SecureDeviceCommandType] AS [SecureDeviceCommandType], 
[Extent2].[CommandRequestedDateTime] AS [CommandRequestedDateTime], 
[Extent2].[CommandExpectedUseDate] AS [CommandExpectedUseDate], 
[Extent2].[EncryptedCommandBytes] AS [EncryptedCommandBytes], 
[Extent2].[TrackingId] AS [TrackingId], 
[Extent2].[IsmKeyType] AS [IsmKeyType], 
[Extent2].[Revision] AS [Revision1], 
[Extent2].[ChangeSetKey] AS [ChangeSetKey1], 
[Extent2].[CommandSetId] AS [CommandSetId], 
[Extent2].[UserAccountKey] AS [UserAccountKey], 
[Extent2].[CommandExecutionDateTime] AS [CommandExecutionDateTime], 
[Extent2].[CommandFailureCode] AS [CommandFailureCode], 
[Extent2].[NotificationAttemptCount] AS [NotificationAttemptCount], 
[Extent2].[NotificationAttemptDateTime] AS [NotificationAttemptDateTime], 
[Extent2].[BusinessUnitDeviceConfigurationFileKey] AS [BusinessUnitDeviceConfigurationFileKey], 
[Extent2].[KeyIndex] AS [KeyIndex], 
[Extent2].[BusinessUnitDeviceConfigurationKey] AS [BusinessUnitDeviceConfigurationKey], 
[Extent2].[ExpirationDate] AS [ExpirationDate], 
[Extent2].[ExternalKey] AS [ExternalKey], 
[Extent3].[Key] AS [Key2], 
[Extent3].[IsmConfigurationKey] AS [IsmConfigurationKey1], 
[Extent3].[DateCreated] AS [DateCreated], 
[Extent3].[KeyIndex] AS [KeyIndex1], 
[Extent3].[IsmKeyType] AS [IsmKeyType1], 
[Extent3].[Revision] AS [Revision2], 
[Extent3].[ChangeSetKey] AS [ChangeSetKey2], 
[Extent3].[SecurityKey] AS [SecurityKey], 
[Extent3].[SecureDeviceKey] AS [SecureDeviceKey1]
FROM   [Fdm].[SecureDevice] AS [Extent1]
LEFT OUTER JOIN [Fdm].[SecureDeviceCommand] AS [Extent2] ON [Extent2].[SecureDeviceKey] = [Extent1].[Key]
LEFT OUTER JOIN [Fdm].[IsmConfigurationSecurityKey] AS [Extent3] ON [Extent3].[SecureDeviceKey] = [Extent1].[Key]
WHERE [Extent1].[DeviceId] IN (N'42423569',N'68000000',N'68000001',N'68000004',N'68000006')

Сгенерированный SQL быстрее. занимает всего 3 секунды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...