SQL Длительный запрос / максимальное использование ресурсов сервера, например, RAM / CPU - PullRequest
0 голосов
/ 17 октября 2018

Первоначально я разместил следующую ветку SQL-запрос - длительный запуск / загрузка ресурсов ЦП

Моя проблема заключалась в том, что мой запрос занимал SARGABILITY (см. Предыдущий поток, но вКороче говоря, я использовал много функций ISNULL, которые обходили сканирование индекса). Теперь у меня возникают дальнейшие проблемы.

Настройки моего сервера SQL следующие:

порог стоимости для параллелизма 5

максимальная степень параллелизма 0

Мой запрос по-прежнему занимает 2:13 для запуска и вызывает скачки ЦП / памяти, у меня в значительной степени работающий сервер, например64 ГБ ОЗУ, поэтому ресурс не проблема.См. Запрос ниже:

WITH CTE AS 
(
    SELECT R.Id AS ResultId,
        r.JobId,
        r.CandidateId,
        R.Email,
        CAST(0 AS BIT) AS EmailSent,
        NULL AS EmailSentDate,
        'PICKUP' AS EmailStatus,
        GETDATE() AS CreateDate,
        C.Id AS UserId,
        C.Email AS UserEmail,
        NULL AS Subject
    FROM RESULTS R
    INNER JOIN JOB J ON R.JobId = J.Id
    INNER JOIN Consultant C ON J.UserId = C.Id
    WHERE 
        J.DCApproved = 1
        AND (J.Closed = 0 OR J.Closed IS NULL)
        AND (R.Email <> '' OR R.Email IS NOT NULL)
        AND (R.EmailSent = 0 OR R.EmailSent IS NULL)
        AND R.EmailSentDate IS NULL -- email has not been sent
        AND (R.EmailStatus = '' OR R.EmailStatus IS NULL)
        AND (R.IsEmailSubscribe = 'True' OR R.IsEmailSubscribe IS NULL)
        -- not already been emailed for this job
        AND NOT EXISTS (
            SELECT SMTP.Email
            FROM SMTP_Production SMTP
            WHERE SMTP.JobId = R.JobId AND SMTP.CandidateId = R.CandidateId
        )
        -- not unsubscribed
        AND NOT EXISTS (        
            SELECT u.Id FROM Unsubscribe u
            WHERE (u.EmailAddress = R.Email OR (u.EmailAddress IS NULL AND R.Email IS NULL)) 
        )
        AND NOT EXISTS (
            SELECT SMTP.Id FROM SMTP_Production SMTP
            WHERE SMTP.EmailStatus = 'PICKUP' AND SMTP.CandidateId = R.CandidateId
        )   
        AND C.Id NOT IN (
            -- LIST OF IDS
        )
        AND J.Id NOT IN (
            -- LIST OF IDS
        )
        AND J.ClientId NOT IN 
        (
            -- LIST OF IDS
        )
)

SELECT 
    CTE.ResultId,
    CTE.JobId,
    CTE.CandidateId,
    CTE.Email,
    CTE.EmailSent,
    CTE.EmailSentDate,
    CTE.EmailStatus,
    CTE.CreateDate,
    CTE.UserId,
    CTE.UserEmail,
    NULL
FROM CTE
  INNER JOIN 
    (
        SELECT *, row_number() over(partition by CTE.Email, CTE.CandidateId order by CTE.EmailSentDate desc) as rn
        FROM CTE

    ) DCTE ON CTE.ResultId = DCTE.ResultId AND DCTE.rn = 1

См. Индексы для таблицы результатов ниже, что-то не так, как показано ниже:

/****** Object:  Index [_dta_index_Results_7_2107154552__K35_K2_K3_K34_K36_K8_K33_K1]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [_dta_index_Results_7_2107154552__K35_K2_K3_K34_K36_K8_K33_K1] ON [dbo].[Results]
(
    [EmailSentDate] ASC,
    [JobId] ASC,
    [AryaCandidateId] ASC,
    [EmailSent] ASC,
    [EmailStatus] ASC,
    [Email] ASC,
    [IsEmailSubscribe] ASC,
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [ACI_CMT_APPLICANTS]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [ACI_CMT_APPLICANTS] ON [dbo].[Results]
(
    [Email] ASC
)
INCLUDE (   [Id],
    [AryaCandidateId]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object:  Index [ACI_Job]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [ACI_Job] ON [dbo].[Results]
(
    [AryaCandidateId] ASC,
    [JobId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object:  Index [ACI_Results]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [ACI_Results] ON [dbo].[Results]
(
    [AryaCandidateId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [gen_smtp_auto]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [gen_smtp_auto] ON [dbo].[Results]
(
    [EmailSentDate] ASC,
    [Email] ASC,
    [IsEmailSubscribe] ASC,
    [EmailSent] ASC,
    [EmailStatus] ASC
)
INCLUDE (   [Id],
    [JobId],
    [AryaCandidateId]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [Hot]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [Hot] ON [dbo].[Results]
(
    [JobId] ASC,
    [Action] ASC
)
INCLUDE (   [Engaged]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object:  Index [IX_Results]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [IX_Results] ON [dbo].[Results]
(
    [Id] ASC,
    [JobId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object:  Index [IX_Results_1]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [IX_Results_1] ON [dbo].[Results]
(
    [Id] ASC,
    [JobId] ASC,
    [AryaCandidateId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [JobMetrics]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [JobMetrics] ON [dbo].[Results]
(
    [JobId] ASC,
    [Source] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [KEY_CAMPAIGN]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [KEY_CAMPAIGN] ON [dbo].[Results]
(
    [ResumeDownloadedDate] ASC,
    [ResumeDownloadStatus] ASC,
    [KeywordCampaignId] ASC,
    [Source] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object:  Index [MISSING_CREATEDATE]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [MISSING_CREATEDATE] ON [dbo].[Results]
(
    [CreateDate] ASC
)
INCLUDE (   [Id]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object:  Index [MISSING_MOVERSPROB]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [MISSING_MOVERSPROB] ON [dbo].[Results]
(
    [MoversProbability] ASC
)
INCLUDE (   [Id]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object:  Index [MISSING_SORTORDER]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [MISSING_SORTORDER] ON [dbo].[Results]
(
    [SortOrder] ASC
)
INCLUDE (   [Id]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [Proto_Resume_Downloa]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [Proto_Resume_Downloa] ON [dbo].[Results]
(
    [JobId] ASC,
    [ResumeDownloadedDate] ASC,
    [ResumeDownloadStatus] ASC,
    [Location] ASC,
    [Source] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [Result_Email]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [Result_Email] ON [dbo].[Results]
(
    [Email] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [Result_Email_Send]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [Result_Email_Send] ON [dbo].[Results]
(
    [EmailSentDate] ASC
)
INCLUDE (   [Id],
    [JobId],
    [AryaCandidateId],
    [Email],
    [IsEmailSubscribe],
    [EmailSent],
    [EmailStatus]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [Results_JobId_ACI_Email]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [Results_JobId_ACI_Email] ON [dbo].[Results]
(
    [JobId] ASC
)
INCLUDE (   [Id],
    [AryaCandidateId],
    [Email]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [RESULTS_JOBID_ALL]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [RESULTS_JOBID_ALL] ON [dbo].[Results]
(
    [JobId] ASC
)
INCLUDE (   [Id],
    [AryaCandidateId],
    [CandidateScore],
    [FirstName],
    [LastName],
    [Telephone],
    [Email],
    [AddressLine1],
    [Location],
    [Postcode],
    [Resume],
    [CurrentJob],
    [CurrentCompany],
    [Skills],
    [Experience],
    [Education],
    [AryaUpdateDate],
    [Industry],
    [Source],
    [LinkedIn],
    [Facebook],
    [Twitter],
    [MoversLabel],
    [MoversProbability],
    [SortOrder],
    [CreateDate],
    [ResumeId],
    [IsEmailSubscribe],
    [EmailSent],
    [EmailSentDate],
    [EmailStatus],
    [Registered],
    [HasVoyagerData],
    [Action],
    [Engaged],
    [FormattedCV],
    [CV],
    [DerivedSource],
    [VoyCode],
    [IsEmailEngaged],
    [IsSMSEngaged],
    [KeywordCampaignId]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [ResultsGetResultsbyConsultantId]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [ResultsGetResultsbyConsultantId] ON [dbo].[Results]
(
    [JobId] ASC
)
INCLUDE (   [Id],
    [AryaCandidateId],
    [CandidateScore],
    [FirstName],
    [LastName],
    [Telephone],
    [Email],
    [AddressLine1],
    [Location],
    [Postcode],
    [Resume],
    [CurrentJob],
    [CurrentCompany],
    [Skills],
    [Experience],
    [Education],
    [AryaUpdateDate],
    [Industry],
    [Source],
    [LinkedIn],
    [Facebook],
    [Twitter],
    [MoversLabel],
    [MoversProbability],
    [DOB],
    [SortOrder],
    [ResumeDownloaded],
    [ResumeDownloadedDate],
    [ResumeDownloadStatus],
    [CreateDate],
    [ResumeId],
    [IsEmailSubscribe],
    [EmailSent],
    [EmailSentDate],
    [EmailStatus],
    [Action],
    [Engaged],
    [SentToArya],
    [IgnoreEmailSent],
    [IgnoreEmailSentDate],
    [FormattedCV],
    [CV],
    [DerivedSource],
    [IsEmailEngaged],
    [IsSMSEngaged]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [Stats_Results_JOB_ACI_ACTION_ENGAGED]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [Stats_Results_JOB_ACI_ACTION_ENGAGED] ON [dbo].[Results]
(
    [JobId] ASC
)
INCLUDE (   [AryaCandidateId],
    [Action],
    [Engaged]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object:  Index [Stats_Results_JobId_ACI]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [Stats_Results_JobId_ACI] ON [dbo].[Results]
(
    [JobId] ASC
)
INCLUDE (   [AryaCandidateId]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [Stats_Results_JobId_ACI_Action_Engaged]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [Stats_Results_JobId_ACI_Action_Engaged] ON [dbo].[Results]
(
    [JobId] ASC
)
INCLUDE (   [AryaCandidateId],
    [Action],
    [Engaged]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [Stats_Results_JobId_ACI_DERIVED]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [Stats_Results_JobId_ACI_DERIVED] ON [dbo].[Results]
(
    [JobId] ASC
)
INCLUDE (   [AryaCandidateId],
    [DerivedSource]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [Stats_Results_JobId_SOURCE_ACI]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [Stats_Results_JobId_SOURCE_ACI] ON [dbo].[Results]
(
    [JobId] ASC,
    [Source] ASC
)
INCLUDE (   [AryaCandidateId]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [Stats_Results_JobId_Source_ACI_V2]    Script Date: 17/10/2018 15:06:18 ******/
CREATE NONCLUSTERED INDEX [Stats_Results_JobId_Source_ACI_V2] ON [dbo].[Results]
(
    [JobId] ASC,
    [Source] ASC
)
INCLUDE (   [AryaCandidateId]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Results] ADD  CONSTRAINT [DF_Results_CreateDate]  DEFAULT (getdate()) FOR [CreateDate]
GO

1 Ответ

0 голосов
/ 17 октября 2018

У меня есть несколько советов, чтобы вы сократили время выполнения:

  1. , если электронное письмо пусто для основной записи, вам не нужно выполнять подзапрос:

поэтому вместо этого утверждения:

AND NOT EXISTS (        
            SELECT u.Id FROM Unsubscribe u
            WHERE (u.EmailAddress = R.Email OR (u.EmailAddress IS NULL AND R.Email IS NULL)) 
        )

используйте приведенное ниже утверждение:

 AND (NOT EXISTS (        
            SELECT u.Id FROM Unsubscribe u
            WHERE u.EmailAddress = R.Email ) 
        ) or  R.Email IS NULL) -- you dont need to check is it is null 
Я рекомендую вам сокращать или обозначать как можно больше, пожалуйста, попробуйте использовать union вместо OR.Некоторые примеры вы можете найти по ссылке ниже:

UNION производительности SQL против OR

как я понял, вы можете использовать JOBID для фильтрации записей SMTP_Production, если вы можете сделать это:

вместо этого оператора

 AND NOT EXISTS (
            SELECT SMTP.Id FROM SMTP_Production SMTP
            WHERE SMTP.EmailStatus = 'PICKUP' AND SMTP.CandidateId = R.CandidateId -- can we add SMTP.JobId = R.JobId
        ) 

, который вы можете использовать ниже

 AND NOT EXISTS (
            SELECT SMTP.Id FROM SMTP_Production SMTP
            WHERE SMTP.EmailStatus = 'PICKUP' AND SMTP.CandidateId = R.CandidateId and SMTP.JobId = R.JobId 
        ) 

окончательная версия запроса может выглядеть следующим образом:

WITH CTE AS 
(
    SELECT R.Id AS ResultId,
        r.JobId,
        r.CandidateId,
        R.Email,
        CAST(0 AS BIT) AS EmailSent,
        NULL AS EmailSentDate,
        'PICKUP' AS EmailStatus,
        GETDATE() AS CreateDate,
        C.Id AS UserId,
        C.Email AS UserEmail,
        NULL AS Subject
    FROM RESULTS R
    INNER JOIN JOB J ON R.JobId = J.Id
    INNER JOIN Consultant C ON J.UserId = C.Id
    WHERE 
        J.DCApproved = 1
        AND (J.Closed <> 1)
        AND (R.Email <> '' OR R.Email IS NOT NULL)
        AND (R.EmailSent <> 1)
        AND R.EmailSentDate IS NULL -- email has not been sent
        AND (R.EmailStatus = '' OR R.EmailStatus IS NULL)
        AND (R.IsEmailSubscribe <> 'False')
        -- not already been emailed for this job
        AND NOT EXISTS (
            SELECT SMTP.Email
            FROM SMTP_Production SMTP
            WHERE SMTP.JobId = R.JobId AND SMTP.CandidateId = R.CandidateId
        )
        -- not unsubscribed
          AND ((NOT EXISTS (        
            SELECT u.Id FROM Unsubscribe u
            WHERE u.EmailAddress = R.Email ) 
        ) or  R.Email IS NULL) )
         AND NOT EXISTS (
            SELECT SMTP.Id FROM SMTP_Production SMTP
            WHERE SMTP.EmailStatus = 'PICKUP' AND SMTP.CandidateId = R.CandidateId and SMTP.JobId = R.JobId 
        ) 
        AND C.Id NOT IN (
            -- LIST OF IDS
        )
        AND J.Id NOT IN (
            -- LIST OF IDS
        )
        AND J.ClientId NOT IN 
        (
            -- LIST OF IDS
        )
)

SELECT 
    CTE.ResultId,
    CTE.JobId,
    CTE.CandidateId,
    CTE.Email,
    CTE.EmailSent,
    CTE.EmailSentDate,
    CTE.EmailStatus,
    CTE.CreateDate,
    CTE.UserId,
    CTE.UserEmail,
    NULL
FROM CTE
  INNER JOIN 
    (
        SELECT *, row_number() over(partition by CTE.Email, CTE.CandidateId order by CTE.EmailSentDate desc) as rn
        FROM CTE

    ) DCTE ON CTE.ResultId = DCTE.ResultId AND DCTE.rn = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...