【发布时间】:2011-08-12 08:58:22
【问题描述】:
以下查询有效,但随着 sendlog 表的大小随时间增加而变慢。目标是从 newsletter_subscribers 表中选择一个列表,其中没有在 newsletter_sendlog 表中具有给定时事通讯 ID 的电子邮件条目。目前,在我的 mysql 服务器上大约需要 2.2 秒,而 sendlog 中只有几千个条目。
SELECT `newsletter_subscribers`.*
FROM `newsletter_subscribers`
INNER JOIN `newsletter_to_subscriber`
ON newsletter_to_subscriber.subscriber_id = newsletter_subscribers.id
LEFT JOIN (
SELECT `newsletter_sendlog`.`subscriber_email`
FROM `newsletter_sendlog`
WHERE (newsletter_id='7')
) AS `sendlog`
ON newsletter_subscribers.email = sendlog.subscriber_email
WHERE (sendlog.subscriber_email IS NULL)
AND (newsletter_to_subscriber.newsletter_id = '7')
EXPLAIN(query) 输出以下内容:
我对 EXPLAIN 的输出不太熟悉,但如果我阅读正确,它会表明它没有使用我在 newsletter_sendlog.subscriber_email 上定义的索引。我试过在那个表上使用 USE INDEX(email) ,但它似乎没有生效。
关于如何优化它的任何建议?或者可能建议另一个相同的查询?
newsletter_sendlog 的创建表:
CREATE TABLE `newsletter_sendlog` (
`id` int(11) unsigned NOT NULL auto_increment,
`subscriber_email` varchar(100) NOT NULL default '',
`newsletter_id` int(11) default NULL,
`sendstatus` int(11) default NULL,
`senddate` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `newsletter_id` (`newsletter_id`),
KEY `email` (`subscriber_email`)
) ENGINE=MyISAM AUTO_INCREMENT=2933 DEFAULT CHARSET=latin1;
为 newsletter_subscribers 创建表:
CREATE TABLE `newsletter_subscribers` (
`id` int(11) unsigned NOT NULL auto_increment,
`email` varchar(100) NOT NULL default '',
`name` tinytext,
PRIMARY KEY (`id`),
KEY `email` (`email`)
) ENGINE=MyISAM AUTO_INCREMENT=2964 DEFAULT CHARSET=utf8;
为 newsletter_to_subscriber 创建表:
CREATE TABLE `newsletter_to_subscriber` (
`id` int(11) unsigned NOT NULL auto_increment,
`newsletter_id` int(11) NOT NULL,
`subscriber_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `newsletter_subscriber` (`newsletter_id`,`subscriber_id`)
) ENGINE=MyISAM AUTO_INCREMENT=2964 DEFAULT CHARSET=latin1;
更新:
在订阅者 ID 上添加索引后,为 newsletter_to_subscriber 创建表现在如下所示:
CREATE TABLE `newsletter_to_subscriber` (
`id` int(11) unsigned NOT NULL auto_increment,
`newsletter_id` int(11) NOT NULL,
`subscriber_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `newsletter_subscriber` (`newsletter_id`,`subscriber_id`),
KEY `subscriber` (`subscriber_id`)
) ENGINE=MyISAM AUTO_INCREMENT=2964 DEFAULT CHARSET=latin1;
@nobody 建议的查询的解释:
【问题讨论】:
标签: mysql performance join query-optimization