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 здесь, чтобы, если в таблице происходит какая-либо операция вставки, мы отдавали приоритет этому запросу, а не этому запросу. Псевдонимы таблиц используются здесь, поскольку мы используем их в состоянии ON.
JOIN
, когда на таблицы больше никогда не ссылаются? Ни в WHERE
, ни в SELECT
, ни в последнем JOIN
. Что касается NOLOCK
, использование подсказки также не означает «Отдавать приоритет другим запросам, кроме этого». Я настоятельно рекомендую прочитать Вредные привычки : везде ставить NOLOCKДля повышения производительности нам нужно просмотреть определения таблицы и индекс и поделиться планом запроса через brentozar.com/pastetheplan. На этот вопрос нельзя ответить без этой информации
У вас есть повторяющиеся существования. Я согласен с ответом, сократите данные, которые вам нужны, во временных таблицах.
Этому может сильно помочь понимание того, как работает SQL. Но я бы порекомендовал вам удалить большинство текстовых полей в объединениях и использовать вместо них их значения int, которые, как я полагаю, существуют.
Например, High_Touch_Account__C = 'true', это, вероятно, следует хранить как BIT внутри БД, и поэтому 1 или 0 будут подходящими, а не 'true'. Точно так же Status = 'Active', вероятно, следует заменить на использование значения int для 'Active'.
Что касается и не существует, я бы, вероятно, создал временную таблицу в начале, в которой собраны все вещи, которые вам не нужны, затем просто выполните левое соединение, а затем в основном «где соединение равно нулю». Это может заменить 25% вашего кода.
NOLOCK также может быть чем-то, на что вам следует обратить внимание.
Если вы загрузите файлы с данными, было бы проще дать вам ответ о наиболее оптимальном способе сделать это, но пока мы не имеем ни малейшего представления о том, какие данные существуют.
boolean
.
Верно, извините, но это дает вам эквивалентное поле под названием BIT, которое вы можете установить на 1 и 0.
bit
и boolean
похожи, но не одинаковы.
Согласен, именно поэтому я использовал слово эквивалент. Если вы не правы, мои первые два слова не были бы "Правда, извините". - Не надо бить лошадь, которую уже покорил.
Эквивалент означает то же самое, @Stoff , поэтому, если это было вашим намерением, эквивалентное слово было неправильным для использования, и поэтому я поправил вас насчет того, что типы данных эквивалентны нет.
Я полагаю, мы оба используем его до крайности так, как нам удобно. Для меня аналогично. Но это также может означать «Очевидно идентичный» и т. д. В этом ответе я хочу сказать, что результат тот же. Не результат самого сервера. Итак, если вы будете утверждать, что BIT обычно используется вместо логического значения и что конечным результатом является 1 для True и 0 для False, и что вы экономите время по сравнению с использованием «True» способа вещей, то я бы сказал, что определение «Похожие или идентичные по значению, смыслу или аффекту» работает, что эквивалентно. <Подобное верно.>
Давайте продолжить обсуждение в чате.
Этот
NOLOCK
спам имеет запах кода; понимаете ли вы, что на самом деле делает эта подсказка запроса (это не означает, что «запрос выполняется быстрее»). У вас также многоINNER JOIN
в CTE, но вы никогда ссылаетесь на таблицы с псевдонимамиAC
,MP
иagr
один раз внеJOIN
s; почему они в запросе?