SQL-запрос занимает много времени для получения результата

WITH
cust AS
    (SELECT DISTINCT
            C.swCustomerId AS EnduserId,
            A.AssetID AS asset,
            suite.ctName AS Product
     FROM ReplicaCADS.dbo.TransactionHeader TH WITH (NOLOCK)
          INNER JOIN ReplicaCRMDB.dbo.SW_CUSTOMER C WITH (NOLOCK) ON C.swCustomerId = TH.EndUserCustomerId
          INNER JOIN ReplicaCADS.dbo.Asset A WITH (NOLOCK) ON TH.TransactionId = A.TransactionId
                                                          AND A.Status = 'Active'
          INNER JOIN ReplicaCADS.dbo.AssetComponent AC WITH (NOLOCK) ON AC.AssetId = A.AssetId
                                                                    AND AC.PrimaryFlag = 1
                                                                    AND AC.Status = 'Active'
          INNER JOIN ReplicaCADS.dbo.MaintenanceProgram MP WITH (NOLOCK) ON MP.AssetId = A.AssetId
                                                                        AND IsLatest = 1
                                                                        AND MP.Status = 'Active'
                                                                        AND MP.EndDate <> '2099-12-31 00:00:00.000'
                                                                        AND MP.MaintenanceType = 'Core'
          INNER JOIN ReplicaCRMDB.dbo.[ct_Product_Suite] suite WITH (NOLOCK) ON suite.ctSuiteID = A.ProductSuiteID
                                                                            AND suite.cTName LIKE 'DaaS'
          INNER JOIN Salesforce.[dbo].[Apttus__APTS_Agreement__c] agr ON agr.Vantive_Org_ID__c = C.ctOrgId
                                                                     AND Apttus__Status__c = 'Activated'
                                                                     AND Agreement_Type__c = 'Licensing'
                                                                     AND agr.Account_Geo__c LIKE 'APAC'
     WHERE NOT EXISTS (SELECT 1
                       FROM salesforce..Priority_Customer__c pr
                       WHERE pr.Account_Org_Id__c = C.CtOrgId)
       AND NOT EXISTS (SELECT 1
                       FROM ReplicaTransactionData..[Transaction] TN
                       WHERE TN.CustomerId = C.swCustomerId
                         AND Status = 'Pending'
                         AND QuoteType IS NULL)
       AND NOT EXISTS (SELECT 1
                       FROM [Salesforce]..Large_Customer__c LDC
                       WHERE LDC.Org_ID__c = C.ctOrgId)
       AND NOT EXISTS (SELECT 1
                       FROM [Salesforce].dbo.Account sac
                       WHERE sac.Org_ID__C = C.ctOrgId
                         AND High_Touch_Account__C = 'true')
       AND NOT EXISTS (SELECT 1
                       FROM salesforce..Priority_Customer__c pr
                       WHERE pr.Account_Org_Id__c = C.ctOrgId)
       AND NOT EXISTS (SELECT 1
                       FROM Salesforce..Asset_Maintenance_Program__c
                       WHERE frmAccount_Org_ID__c = C.ctOrgId
                         AND Maintenance_Type__c IN ('Advanced'))
       AND EXISTS (SELECT 1
                   FROM ReplicaCADS..AssetpricingData AP
                   WHERE AP.AssetId = A.AssetId))
SELECT TOP 1
       P.swLogin AS LoginId
FROM cust
     INNER JOIN ReplicaCRMDB.dbo.SW_PERSON P WITH (NOLOCK) ON P.swCustomerId = EnduserId
                                                          AND P.swStatus = 'Current'
                                                          AND SWLogin IS NOT NULL
                                                          AND P.ctLocale = 'en-US'
     INNER JOIN ReplicaCRMDB.dbo.CT_CONTACT_TYPE Contact WITH (NOLOCK) ON Contact.swContactId = P.swPersonId
     INNER JOIN ReplicaCRMDB.dbo.CT_MC_USERS MCUsers ON MCUsers.swPersonID = P.swPersonId
                                                    AND (MCUsers.ctPassword = '32CA9FC1A0F5B6330E3F4C8C1BBECDE9BEDB9573'
                                                      OR MCUsers.ctPassword = '')
ORDER BY NEWID();

При попытке использовать оба приведенных ниже условия вместе это занимает много времени.

AND NOT EXISTS (SELECT 1
                  FROM Salesforce..Asset_Maintenance_Program__c
                  WHERE frmAccount_Org_ID__c = C.ctOrgId
                    AND Maintenance_Type__c IN ('Advanced'))
AND EXISTS (SELECT 1
            FROM ReplicaCADS..AssetpricingData AP
            WHERE AP.AssetId = A.AssetId)

Не могли бы вы помочь мне как-то настроить приведенный выше запрос, чтобы быстро получить результат?

Этот NOLOCK спам имеет запах кода; понимаете ли вы, что на самом деле делает эта подсказка запроса (это не означает, что «запрос выполняется быстрее»). У вас также много INNER JOIN в CTE, но вы никогда ссылаетесь на таблицы с псевдонимами AC, MP и agr один раз вне JOINs; почему они в запросе?

Larnu 22.03.2022 11:27

пойте NOLOCK здесь, чтобы, если в таблице происходит какая-либо операция вставки, мы отдавали приоритет этому запросу, а не этому запросу. Псевдонимы таблиц используются здесь, поскольку мы используем их в состоянии ON.

Gamer 22.03.2022 11:35
«Здесь используются псевдонимы таблиц, поскольку мы используем их в состоянии ON». Это не ответ на мой вопрос. Почему JOIN, когда на таблицы больше никогда не ссылаются? Ни в WHERE, ни в SELECT, ни в последнем JOIN. Что касается NOLOCK, использование подсказки также не означает «Отдавать приоритет другим запросам, кроме этого». Я настоятельно рекомендую прочитать Вредные привычки : везде ставить NOLOCK
Larnu 22.03.2022 11:38

Для повышения производительности нам нужно просмотреть определения таблицы и индекс и поделиться планом запроса через brentozar.com/pastetheplan. На этот вопрос нельзя ответить без этой информации

Charlieface 22.03.2022 11:49

У вас есть повторяющиеся существования. Я согласен с ответом, сократите данные, которые вам нужны, во временных таблицах.

Nathan_Sav 22.03.2022 12:13
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
5
39
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Например, High_Touch_Account__C = 'true', это, вероятно, следует хранить как BIT внутри БД, и поэтому 1 или 0 будут подходящими, а не 'true'. Точно так же Status = 'Active', вероятно, следует заменить на использование значения int для 'Active'.

Что касается и не существует, я бы, вероятно, создал временную таблицу в начале, в которой собраны все вещи, которые вам не нужны, затем просто выполните левое соединение, а затем в основном «где соединение равно нулю». Это может заменить 25% вашего кода.

NOLOCK также может быть чем-то, на что вам следует обратить внимание.

Если вы загрузите файлы с данными, было бы проще дать вам ответ о наиболее оптимальном способе сделать это, но пока мы не имеем ни малейшего представления о том, какие данные существуют.

"это, вероятно, следует хранить как логическое значение" SQL Server не имеет типа данных boolean.
Larnu 22.03.2022 11:52

Верно, извините, но это дает вам эквивалентное поле под названием BIT, которое вы можете установить на 1 и 0.

Stoff 22.03.2022 11:53
bit и boolean похожи, но не одинаковы.
Larnu 22.03.2022 11:53

Согласен, именно поэтому я использовал слово эквивалент. Если вы не правы, мои первые два слова не были бы "Правда, извините". - Не надо бить лошадь, которую уже покорил.

Stoff 22.03.2022 11:54

Эквивалент означает то же самое, @Stoff , поэтому, если это было вашим намерением, эквивалентное слово было неправильным для использования, и поэтому я поправил вас насчет того, что типы данных эквивалентны нет.

Larnu 22.03.2022 11:56

Я полагаю, мы оба используем его до крайности так, как нам удобно. Для меня аналогично. Но это также может означать «Очевидно идентичный» и т. д. В этом ответе я хочу сказать, что результат тот же. Не результат самого сервера. Итак, если вы будете утверждать, что BIT обычно используется вместо логического значения и что конечным результатом является 1 для True и 0 для False, и что вы экономите время по сравнению с использованием «True» способа вещей, то я бы сказал, что определение «Похожие или идентичные по значению, смыслу или аффекту» работает, что эквивалентно. <Подобное верно.>

Stoff 22.03.2022 12:04

Давайте продолжить обсуждение в чате.

Stoff 22.03.2022 12:04

Другие вопросы по теме