Mysql
為什麼索引沒有加速多連接查詢
好的,所以我有 3 個表:聯繫人、便箋和 lastContact。
問題是: 1) 每當我想將聯繫人雙重連接到其他 2 個表時,查詢會在 15-60 分鐘內爆炸。2)為什麼使用目前索引只是主表中的主鍵計數到其他 2 個表需要這麼多時間?
它們都有一個共同的鍵,除了音符之外是獨一無二的。
(結構簡化刪除所有不必要的列)
CREATE TABLE `contacts` ( `contactID` int(10) unsigned NOT NULL AUTO_INCREMENT, `firstName` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL, `lastName` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL, `phone` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL, `mobilePhone` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL, `altPhone` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL, `street` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, `city` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL, `state` varchar(3) COLLATE utf8_unicode_ci DEFAULT NULL, `postalCode` varchar(12) COLLATE utf8_unicode_ci DEFAULT NULL, `email` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL, `source` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL, `owner` varchar(64) unsigned DEFAULT NULL, PRIMARY KEY (`contactID`), KEY `phone` (`phone`), KEY `phones` (`phone`,`mobilePhone`,`altPhone`), KEY `owner` (`owner`), KEY `source` (`contactID`,`source`,`owner`) ) ENGINE=InnoDB AUTO_INCREMENT=119138 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; CREATE TABLE `contacts_notes` ( `noteID` int(10) unsigned NOT NULL AUTO_INCREMENT, `contactID` int(10) unsigned DEFAULT NULL, `notes` text, `dateline` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`noteID`), KEY `contactID` (`contactID`) ) ENGINE=Aria AUTO_INCREMENT=1486 DEFAULT CHARSET=utf8 PAGE_CHECKSUM=1; CREATE TABLE `lastContacts` ( `contactID` varchar(32) COLLATE utf8_unicode_ci NOT NULL, `ultimo` datetime DEFAULT NULL, `callID` int(10) unsigned DEFAULT NULL, `userName` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL, `lastContact` datetime DEFAULT NULL, `callCount` tinyint(3) unsigned DEFAULT NULL, PRIMARY KEY (`contactID`), KEY `callid` (`callID`), KEY `ultimo` (`ultimo`), KEY `username` (`userName`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
在contacts 和lastContacts 中有~50k 記錄,contact_notes 有~1k。
查詢是:
SELECT COUNT(*) total FROM ( SELECT l.contactID FROM contacts l LEFT JOIN lastContacts lc ON l.contactID = lc.contactID WHERE lc.contactID IS NULL ) x LEFT JOIN contacts_notes ln ON x.contactID = ln.contactID WHERE ln.contactID IS NULL
@Jehad Keraki 提供了答案。表
lastContacts
的主鍵列ContactID
被定義為字元串,而其他每個表中的同一列是整數。在該列上連接表會導致隱式轉換並導致性能不佳。