我有一个约280万行,3列的表。每行代表公司的营销方式,并且具有“customer_id”,“marketing_type”和“week_num”。“customer_id”上有索引,“marketing_type”上有另一个索引
数据的一个例子:
72, catalog, 7
72, email, 3
99, catalog, 13
82, catalog, 7
我需要一个包含电子邮件但没有目录的所有customer_id的列表。 (还有其他类型的营销,而且还有没有得到任何东西的customer_id)
首先尝试:
SELECT DISTINCT cust_id
FROM marketing_campaign
WHERE marketing_type = 'email'
AND cust_id NOT IN (
SELECT cust_id
FROM marketing_campagin
WHERE marketing_type = 'catalog'
)
;
此查询需要30多分钟才能运行
SELECT m1.cust_id
FROM marketing_campaign m1
LEFT OUTER JOIN marketing_campaign m2
ON m1.cust_id = m2.cust_id
AND m2.MARKETING_TYPE = 'catalog'
WHERE m1.MARKETING_TYPE = 'email'
AND m2.cust_id IS NULL
;
此查询在3.8秒内执行,但提取时间超过30分钟。
SELECT distinct cust_id
FROM marketing_campaign a
WHERE MARKETING_TYPE = 'email'
AND NOT EXISTS (
SELECT 'X'
FROM marketing_campaign b
WHERE a.cust_id = b.cust_id
AND MARKETING_TYPE = 'catalog'
)
ORDER BY cust_id
;
此查询也在< 5秒内执行,但随后提取超过20分钟。
答案 0 :(得分:2)
不要忽视复合索引:
ALTER TABLE marketing_campaign ADD KEY (marketing_type, cust_id);
然后使用查询#2。
另外,请确保已将缓冲区调整得足够大,以使索引驻留在RAM中。