Это похоже на запрос, который добавлялся снова и снова, с большим количеством повторений кода и множеством ненужных сканирований таблиц.
Поймите, что я больше всего знаком с MS SQL, а не с красным смещением , но для большинства будут применяться те же принципы.
(
lower(xa.primary_function) in (
select
lower(param_val)
from
ce_campaign_spec_tb
where
job_id = '1d8db587-f5ab-41f4-9c2b-c4e21e0c7481'
and param = 'primary_function'
and relation_id = 4
)
and lower(xa.role) in (
select
lower(param_val)
from
ce_campaign_spec_tb
where
job_id = '1d8db587-f5ab-41f4-9c2b-c4e21e0c7481'
and param = 'role'
and relation_id = 4
)
and lower(xa.title) in (
select
lower(title)
from
contacts con
inner join ce_campaign_spec_tb camp on lower(con.title) ilike '%' || trim(
both ' '
from
camp.param_val
) || '%'
where
job_id = '1d8db587-f5ab-41f4-9c2b-c4e21e0c7481'
and param = 'title'
and relation_id = 4
)
)
, не зная, что это делает, вы, кажется, повторяете этот блок кода 5 раз с единственным изменением, которое изменилось: Relationship_id. Вы начинаете с идентификатора 4, затем 2, затем 1, затем 3 и затем 5, но кроме идентификатора ничего не меняется. могут быть небольшие различия, но теперь вы начинаете сканировать таблицы 5 раз, а не один раз с одним предикатом. в зависимости от размера таблиц это может быть изрядный объем данных, которые вы сканируете
несколько строк дальше:
and xa.contact_id not in (
select
contact_id
from
bh_leads
where
(CURRENT_DATE - creation_date :: date) <= 60
and UPPER(LOB) = 'ABC'
and agency_id = '1002'
)
and xa.contact_id not in (
select
contact_id
from
bh_leads
where
(CURRENT_DATE - creation_date :: date) <= 60
and UPPER(LOB) = 'ABC'
and sponsor_id = '8306'
)
снова 2 сканирования таблиц для практически тех же данных, с той лишь разницей, что on проверяет значение спонсора_id, а другое - agency_id. это можно было бы сделать в одном выражении вместо 2
ниже:
and email_id not in (
select
distinct email_id
from
contacts
where
is_email_suppressed = 1
)
ранее вы ссылались на контакт (xa) и поместили это как предикат в предложение where:
and xa.is_email_suppressed = 0
, не зная точной схемы рассматриваемых таблиц, я не могу быть уверен, но, похоже, они делают в основном то же самое.
также, из документации Redshift здесь: https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html
кажется, вы можете создавать временные таблицы на время одного сеанса. большинство подзапросов можно подготовить, чтобы вы могли присоединиться к набору результатов. если вы сначала подготовите, например, временный набор результатов для таблицы campaign_extraction_history с действительными результатами, вы можете заменить следующие предикаты одним левым соединением:
AND contact_id NOT IN (
select
contact_id
from
campaign_extraction_history
where
sf_oms_campaign_id = 'ABC-013505-2-2020'
and sf_campaign_id = 'ABC-013505'
and (CURRENT_DATE - creation_date :: date) < 1
and channel = 'BOTH'
and (
UPPER(STATUS) = 'EXTRACTED'
OR UPPER(STATUS) = 'LAUNCHED'
OR UPPER(STATUS) = 'CONFIRMED'
)
)
AND contact_id NOT IN (
select
contact_id
from
campaign_extraction_history
where
creation_date :: date = CURRENT_DATE
and channel = 'BOTH'
and (
UPPER(STATUS) = 'EXTRACTED'
OR UPPER(STATUS) = 'LAUNCHED'
OR UPPER(STATUS) = 'CONFIRMED'
)
group by
contact_id
having
count(*) > 10
)
AND contact_id NOT IN (
select
contact_id
from
campaign_extraction_history
where
sf_campaign_id = 'ABC-013505'
and channel = 'BOTH'
and (
UPPER(STATUS) = 'EXTRACTED'
OR UPPER(STATUS) = 'LAUNCHED'
OR UPPER(STATUS) = 'CONFIRMED'
)
group by
contact_id
having
count(*) >= 3
)
есть, вероятно, больше мест, где вы можете комбинировать запросы и получать данные из таблиц всего за один раз. например, вы исключаете множество значений email_id, но в разных местах в разных операторах и подзапросах. они, скорее всего, могут быть выполнены в одном операторе.
возможно, лучший способ повысить производительность - это спросить себя, что запрос пытается сделать и исключить, а затем просто переписать весь запрос. это может быть изрядно трудоемким делом, но в конечном итоге может оказаться быстрее.