2

我的问题

我们有一个电子邮件引擎,它以块的形式向用户发送电子邮件(向许多用户发送相同的电子邮件:即批量通讯)或单个案例(向一个用户发送一封电子邮件:即密码重置)。我们有一个管理控制台,它显示已发送电子邮件的日志。

现在,这个表有大约 750,000 行。对于发送的每个 EMAIL,表中都会记录以下内容(精简到主要项目):

  • ID
  • batch_id
  • 用户身份
  • 主题
  • 发送日期
  • 创建

如果发送了一批电子邮件,则该批中的所有电子邮件都将具有相同的batch_id. 当管理员浏览日志控制台时,我们不想在表格结果中显示来自批次的所有电子邮件 - 只是一个唯一的。所以我们这样做了:

SELECT id, batch_id, user_id, subject, send_date, created FROM `emails` 
GROUP BY batch_id
ORDER BY created DESC
limit 10

这有效,但速度很慢。这是我们对查询的 EXPLAIN 的结果:

+----+-------------+-------------+-------+---------------+----------+---------+------+------+---------------------------------+
| id | select_type | table       | type  | possible_keys | key      | key_len | ref  | rows | Extra                           |
+----+-------------+-------------+-------+---------------+----------+---------+------+------+---------------------------------+
|  1 | SIMPLE      | emails_logs | index | NULL          | batch_id | 17      | NULL | 2522 | Using temporary; Using filesort |
+----+-------------+-------------+-------+---------------+----------+---------+------+------+---------------------------------+
1 row in set (0.00 sec)

我们的目标

快速选择 的唯一记录batch_id,按记录创建日期降序排列。

我的问题是:如何以最佳方式索引这些,并以适当的方式选择字段以利用这些索引?

谢谢!

4

1 回答 1

1

这是一个想法。在 上创建一个索引emails(created, batchid),另一个在emails(batchid). 现在做:

select e.id, e.batch_id, e.user_id, e.subject, e.send_date, e.created
from (select batchid, created
      from emails
      order by created desc
      limit 10
     ) e10 join
     emails e
     on e.batchid = e10.batchid
group by e.batchid
order by created desc;

这个想法是在进行聚合和排序之前减少您正在处理的集合。

听起来如果您的数据更加规范化,您的数据会更好。一个表应该有批次信息,包括发件人和创建日期。另一个应该有

于 2013-08-28T13:28:11.913 回答