Я разрабатываю систему маркетинга. На первой странице одним из требований является то, что сотрудники отдела продаж видят количество возможностей продаж, которые они в настоящее время имеют.Как оптимизировать сложный запрос?
ie.
Birthdays | 10
Anniversaries | 15
Introductions | 450
Recurring | 249
Проблема в том, что я UNION
ИНГ все это и запрос принимает более 10 секунд в некоторых случаях. (У нас есть кеширование на месте, так что это проблема только при первом входе пользователя в систему в течение дня).
Существует много других критериев участвуют:
- включены в счет должен быть только последним один на одного клиента для каждого типа (то есть, если у клиента есть два введений, она должна учитываться только один раз -. Я использую greatest-n-per-group способ достижения этого)
- для рождения и юбилеев, дата должна быть +/- 7 дней от сегодня
- для всех из них, только записи за последние 60 дней должна быть подсчитана
- эти записи должны быть объединены ред с таблицей клиентов, чтобы убедиться, что продажи возможности в лице соответствует текущим продажам лица клиента
Здесь генерируются запрос (Длинна):
SELECT 'Birthdays' AS `type`, COUNT(*) AS `num`
FROM `opportunities`
INNER JOIN `customers`
ON `opportunities`.`customer_id` = `customers`.`customer_id`
AND `opportunities`.`sales_person_id` = `customers`.`sales_person_id`
LEFT JOIN `opportunities` AS `o2`
ON `opportunities`.`customer_id` = `o2`.`customer_id`
AND `opportunities`.`marketing_message` = `o2`.`marketing_message`
AND opportunities.communication_alert_date < o2.communication_alert_date
WHERE ((`opportunities`.`org_code` = ?))
AND (opportunities.marketing_message = 'Birthday Alert')
AND ((opportunities.communication_alert_date BETWEEN
DATE_SUB(NOW(), INTERVAL 7 DAY) AND DATE_ADD(NOW(), INTERVAL 7 DAY)))
AND (opportunities.communication_alert_date >= DATE_SUB(NOW(), INTERVAL 60 DAY))
AND (o2.customer_id IS NULL)
UNION ALL
SELECT 'Anniversaries' AS `type`, COUNT(*) AS `num`
FROM `opportunities`
INNER JOIN `customers`
ON `opportunities`.`customer_id` = `customers`.`customer_id`
AND `opportunities`.`sales_person_id` = `customers`.`sales_person_id`
LEFT JOIN `opportunities` AS `o2`
ON `opportunities`.`customer_id` = `o2`.`customer_id`
AND `opportunities`.`marketing_message` = `o2`.`marketing_message`
AND opportunities.communication_alert_date < o2.communication_alert_date
WHERE ((`opportunities`.`org_code` = ?))
AND (opportunities.marketing_message = 'Anniversary Alert')
AND ((opportunities.communication_alert_date BETWEEN
DATE_SUB(NOW(), INTERVAL 7 DAY) AND DATE_ADD(NOW(), INTERVAL 7 DAY)))
AND (opportunities.communication_alert_date >= DATE_SUB(NOW(), INTERVAL 60 DAY))
AND (o2.customer_id IS NULL)
UNION ALL
SELECT 'Introductions' AS `type`, COUNT(*) AS `num`
FROM `opportunities`
INNER JOIN `customers`
ON `opportunities`.`customer_id` = `customers`.`customer_id`
AND `opportunities`.`sales_person_id` = `customers`.`sales_person_id`
LEFT JOIN `opportunities` AS `o2`
ON `opportunities`.`customer_id` = `o2`.`customer_id`
AND `opportunities`.`marketing_message` = `o2`.`marketing_message`
AND opportunities.communication_alert_date < o2.communication_alert_date
WHERE ((`opportunities`.`org_code` = ?))
AND ((opportunities.Intro_Letter = 'Yes'))
AND (opportunities.communication_alert_date >= DATE_SUB(NOW(), INTERVAL 60 DAY))
AND (o2.customer_id IS NULL)
UNION ALL
SELECT 'Recurring' AS `type`, COUNT(*) AS `num`
FROM `opportunities`
INNER JOIN `customers`
ON `opportunities`.`customer_id` = `customers`.`customer_id`
AND `opportunities`.`sales_person_id` = `customers`.`sales_person_id`
LEFT JOIN `opportunities` AS `o2`
ON `opportunities`.`customer_id` = `o2`.`customer_id`
AND `opportunities`.`marketing_message` = `o2`.`marketing_message`
AND opportunities.communication_alert_date < o2.communication_alert_date
WHERE ((`opportunities`.`org_code` = ?))
AND ((opportunities.marketing_message != 'Anniversary Alert'
AND opportunities.marketing_message != 'Birthday Alert'
AND opportunities.Intro_Letter != 'Yes'))
AND (opportunities.communication_alert_date >= DATE_SUB(NOW(), INTERVAL 60 DAY))
AND (o2.customer_id IS NULL)
У меня есть индексы по следующим направлениям в opportunities
таблице:
- org_code
- customer_id
- Intro_Letter
- marketing_message
- sales_person_id
- org_code, marketing_message
- org_code, Intro_Letter
- org_code, marketing_message, Intro_Letter
Любая помощь оптимизируя это было бы весьма признателен. Я открыт для создания других таблиц или представлений, если это необходимо.
, чтобы процитировать 'или не указывать - вот вопрос –