我有两个表,一个有大约700行,另一个有超过100,000行。
我的查询是查找第一个表中第二个表中不存在电子邮件地址的所有行。
SELECT a.*
FROM `csv_import_temp` a FORCE INDEX FOR JOIN (`imp_email`)
LEFT JOIN `xlefz_mailer_Contacts` b FORCE INDEX FOR JOIN (`idx_contact_email`)
ON a.`contact_email` like b.`contact_email`
WHERE b.`contact_email` is null
两个表中的contact_email都有索引。该查询的解释显示,即使在我添加了FORCE INDEX子句之后,也只使用了其中一个索引。
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
1 | SIMPLE | a | ALL | NULL | NULL | NULL | NULL | 292 |
1 | SIMPLE | b | index | NULL | idx_contact_email | 228 | NULL | 106149 | Using where; Using index
目前查询只需6秒钟即可运行。
如何让查询使用这两个索引?
第一张表:
CREATE TABLE `csv_import_temp` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`contact_lname` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT 'Last or Family name',
`contact_email` varchar(75) COLLATE utf8_unicode_ci DEFAULT '' COMMENT 'Email Address',
`contact_state` varchar(20) COLLATE utf8_unicode_ci DEFAULT '' COMMENT 'State or provence',
`contact_country` varchar(25) CHARACTER SET utf8 DEFAULT 'USA' COMMENT 'Country Name or Code',
`contact_oktoemail` enum('Yes','No') COLLATE utf8_unicode_ci DEFAULT 'Yes' COMMENT 'Yes if OK to send Email',
`contact_oktofax` enum('Yes','No') COLLATE utf8_unicode_ci DEFAULT 'Yes' COMMENT 'Yes of Ok to send Fax',
`contact_oktomail` enum('Yes','No') COLLATE utf8_unicode_ci DEFAULT 'Yes' COMMENT 'Yes of OK to send mail',
`contact_status` enum('Ok','Unsub','Bounced','BouncedUpdated','isAOL') COLLATE utf8_unicode_ci DEFAULT 'Ok' COMMENT 'Ok - can contact via email, Unsub if unsubscribe request has been received. Bounced = Mail sent to email address bounced.',
PRIMARY KEY (`id`),
KEY `imp_email` (`contact_email`)
) ENGINE=MyISAM AUTO_INCREMENT=293 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
第二张表:
CREATE TABLE `xlefz_mailer_Contacts` (
`contact_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`contact_created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Timestamp when record was created',
`contact_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Timestamp when record was last modified',
`manual_update` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'If 1, has been manually updated',
`manual_updateDT` timestamp NULL DEFAULT NULL COMMENT 'Timestamp of last manual update',
`contact_import_id` int(11) DEFAULT NULL,
`contact_company` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT 'Company Name',
`contact_title` varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT 'Mr., Ms., Dr., etc.',
`contact_fname` varchar(50) CHARACTER SET utf8 NOT NULL DEFAULT '' COMMENT 'First or given name',
`contact_lname` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT 'Last or Family name',
`contact_email` varchar(75) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Email Address',
`contact_email_name` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'The mart of an email address before the @',
`contact_email_domain` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'The mart of an email address after the @',
`contact_addr1` varchar(50) COLLATE utf8_unicode_ci DEFAULT '' COMMENT '1st line of mailing address',
`contact_addr2` varchar(50) COLLATE utf8_unicode_ci DEFAULT '' COMMENT 'Apartment, suite, etc.',
`contact_city` varchar(50) COLLATE utf8_unicode_ci DEFAULT '' COMMENT 'City',
`contact_state` varchar(20) COLLATE utf8_unicode_ci DEFAULT '' COMMENT 'State or provence',
`contact_zip` varchar(15) COLLATE utf8_unicode_ci DEFAULT '' COMMENT 'Postal code',
`contact_country` varchar(25) CHARACTER SET utf8 DEFAULT NULL COMMENT 'Country Name or Code',
`contact_phone` varchar(20) COLLATE utf8_unicode_ci DEFAULT '' COMMENT 'Voice Phone',
`contact_fax` varchar(20) COLLATE utf8_unicode_ci DEFAULT '' COMMENT 'Fax Phone',
`contact_oktoemail` enum('Yes','No') COLLATE utf8_unicode_ci DEFAULT 'Yes' COMMENT 'Yes if OK to send Email',
`contact_oktofax` enum('Yes','No') COLLATE utf8_unicode_ci DEFAULT 'Yes' COMMENT 'Yes of Ok to send Fax',
`contact_oktomail` enum('Yes','No') COLLATE utf8_unicode_ci DEFAULT 'Yes' COMMENT 'Yes of OK to send mail',
`contact_notes` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Notes regarding contact.',
`contact_status` enum('Ok','Unsub','Bounced','BouncedUpdated','isAOL') COLLATE utf8_unicode_ci DEFAULT 'Ok' COMMENT 'Ok - can contact via email, Unsub if unsubscribe request has been received. Bounced = Mail sent to email address bounced. BouncedUpdated - indicates that the contact has been copied and updated with a new email address',
PRIMARY KEY (`contact_id`),
KEY `idx_contact_email` (`contact_email`),
KEY `idx_contact_city` (`contact_city`),
KEY `idx_contact_country` (`contact_country`),
KEY `idx_contact_oktoemail` (`contact_oktoemail`),
KEY `idx_contact_oktofax` (`contact_oktofax`),
KEY `idx_contact_oktomail` (`contact_oktomail`),
KEY `contact_import_id` (`contact_import_id`),
KEY `idx_contact_oktoemailstatus` (`contact_oktoemail`,`contact_status`),
KEY `contact_email_name` (`contact_email_name`,`contact_email_domain`),
KEY `idx_mailer_contacts_manualupdate` (`manual_update`),
KEY `idx_mailer_contact_manualupdateDT` (`manual_updateDT`)
) ENGINE=MyISAM AUTO_INCREMENT=128829 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
答案 0 :(得分:4)
澄清问题中的一些误解:
总而言之,您应该为连接条件使用相等,或者您可以将查询重写为以下,恕我直言,更简单的查询:
SELECT *
FROM csv_import_temp
WHERE contact_email NOT IN (
SELECT contact_email FROM xlefz_mailer_Contacts);