SQL IN в случае, когда условие вызывает проблемы производительности с большими данными - PullRequest
2 голосов
/ 24 января 2020

Следующий запрос отлично работает в моей базе данных, но он вызывает огромные проблемы с производительностью в клиентской БД. Я знаю, что я использую предложение IN в условии where, которое вызывает у меня эту проблему. Но я не знаю, как это исправить.

declare @AccountId int
set @AccountId =  1200
declare @IsLinkedAccountsNotes bit
set @IsLinkedAccountsNotes =1
declare @EventType varchar(100)
set @EventType = ''

SELECT
        u.loginName as InteractionLoginName,
        u.userName as InteractionUserName,
        e.*
    FROM
        lat.events e
        INNER JOIN dbo.MasterEvents me ON me.EventId = e.EventId    
        LEFT JOIN dbo.Users u ON e.UserId = u.ID 
    WHERE
        (me.AccountId = @AccountId OR
        (@IsLinkedAccountsNotes = 1 AND me.AccountId IN (SELECT DISTINCT [number] FROM dbo.Linking_LinkedAccounts WHERE linked_number = @AccountId) AND e.EventType = 'AccountNoteAdded'))

Я знаю, что второе условие в предложении where вызывает проблему. И я видел в различных сообщениях, что с помощью объединения решит эту проблему. Но я не понимаю, как использовать соединение внутри, где условия. Или есть другой подход к тому же.

Пожалуйста, помогите.

Ответы [ 2 ]

2 голосов
/ 24 января 2020

Ваша проблема, вероятно, в том, что это "запрос всех запросов". Вы можете попробовать разделить случаи, как показано ниже:

SELECT u.loginName AS InteractionLoginName,
       u.userName  AS InteractionUserName,
       e.*
FROM   lat.events e
       INNER JOIN dbo.MasterEvents me
               ON me.EventId = e.EventId
       LEFT JOIN dbo.Users u
              ON e.UserId = u.ID
WHERE  me.AccountId = @AccountId
UNION ALL
SELECT u.loginName AS InteractionLoginName,
       u.userName  AS InteractionUserName,
       e.*
FROM   lat.events e
       INNER JOIN dbo.MasterEvents me
               ON me.EventId = e.EventId
       LEFT JOIN dbo.Users u
              ON e.UserId = u.ID
WHERE  @IsLinkedAccountsNotes = 1
       AND e.EventType = 'AccountNoteAdded'
       AND me.AccountId IN (SELECT [number]
                            FROM   dbo.Linking_LinkedAccounts
                            WHERE  linked_number = @AccountId
                                   AND [number] <> @AccountId) 
0 голосов
/ 24 января 2020

Можно попробовать что-то вроде

JOIN (SELECT DISTINCT [number] FROM dbo.Linking_LinkedAccounts WHERE linked_number = @AccountId) lla ON lla.number = me.AccountId

LEFT JOIN и отфильтровать нулевые значения в условии условия.

EXISTS вместо IN.

...