Следующий запрос работает, но становится медленнее, так как размер таблицы sendlog со временем увеличивается.Цель состоит в том, чтобы выбрать список всех подписчиков из таблицы newsletter_subscribeers, которые не имеют запись электронной почты для данного идентификатора бюллетеня в таблице newsletter_sendlog.В настоящее время это занимает около 2,2 секунд на моем сервере MySQL с только пару тысяч записей в 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 (запрос) выводит следующее:
Я не слишком знаком с выводом EXPLAIN,но если я прочитал его правильно, это может означать, что он не использует индекс, который я определил в newsletter_sendlog.subscriber_email.Я пытался использовать USE INDEX (электронную почту) для этой таблицы, но, похоже, это не сработало.
Есть предложения, как это оптимизировать?Или, возможно, предложить другой запрос, который делает то же самое?
Создать таблицу для 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_subscribeers:
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;
Обновление:
Создание таблицы для newsletter_to_subscriber теперь выглядит следующим образом после добавления индекса для subscriber_id:
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: