我正在开发一个营销型系统。在首页上,销售人员需要查看其当前销售机会的数量。如何优化复杂查询?
即。
Birthdays | 10
Anniversaries | 15
Introductions | 450
Recurring | 249
的问题是我UNION
荷兰国际集团所有这些和查询接管在某些情况下10秒。 (我们有缓存,所以这只是用户第一次登录的那一天的问题)。
这牵涉到很多其他标准:
计算在内- 应该只是每类客户(即,最后一个,如果客户有两个介绍,它应该只计算一次 - 。我使用的解决这个问题的方法greatest-n-per-group)
- 生日和纪念日的日期应该是从今天
- +/- 7天,所有的人,在过去60天内只记录应该算
- 这些记录需要加入ED与客户表,以确保机会的销售人员对客户当前的销售人员
匹配下面是生成的查询(长):
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
任何优化这种帮助将不胜感激。如果需要,我愿意创建其他表或视图。
要引用'或不引用 - 这是 – 2010-11-18 21:01:07