Je développe un système de type marketing. En première page, l'une des exigences est que le personnel des ventes puisse voir le nombre d'opportunités de ventes qu'ils ont actuellement.Comment optimiser une requête complexe?
ie.
Birthdays | 10
Anniversaries | 15
Introductions | 450
Recurring | 249
Le problème est que je suis UNION
ing tous ces éléments et la requête reprend 10s dans certains cas. (La mise en cache est en place, ce qui pose problème uniquement la première fois qu'un utilisateur se connecte pour la journée).
Il y a beaucoup d'autres critères impliqués:
- inclus dans le décompte ne devrait être le dernier par client par type (par exemple, si un client a deux introductions, il ne doit être compté qu'une seule fois -. J'utilise la méthode greatest-n-per-group d'y parvenir)
- pour les anniversaires, la date devrait être +/- 7 jours à compter d'aujourd'hui
- pour tous, seuls les enregistrements dans les 60 derniers jours devraient être comptés
- ces enregistrements doivent être rejoindre ed avec les clients table pour faire en sorte que la personne de vente opportunité correspond à la personne de vente actuel du client
Voici la requête générée (elle est longue):
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)
Je index sur les champs suivants dans le tableau 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
Toute aide l'optimisation de ce serait grandement apprécié. Je suis ouvert à la création d'autres tables ou vues si nécessaire.
pour citer 'ou ne pas citer - c'est la question –