mysql连接字段需要索引_mysql – 索引字段上的连接不使用索引
我有兩張桌子.我寫了一個查詢來在一列上加入它們.此列在兩個表中都已編制索引,但MySQL未使用索引.有人a)告訴我為什么和b)告訴我如何讓MySQL使用索引快速加入這些表.
第一張表:
CREATE TABLE `dol_msa_zip_assoc` (
`pkey` int(5) unsigned NOT NULL AUTO_INCREMENT,
`zip` varchar(5) NOT NULL DEFAULT '',
`pmsa_msa` varchar(5) NOT NULL DEFAULT '',
PRIMARY KEY (`pkey`),
KEY `zip` (`zip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
它包含42690條記錄.
另一張桌子:
CREATE TABLE `v3_msa_zip_assoc` (
`pkey` int(5) unsigned NOT NULL AUTO_INCREMENT,
`zip` varchar(9) NOT NULL DEFAULT '',
`pmsa_msa` varchar(6) NOT NULL DEFAULT '',
PRIMARY KEY (`pkey`),
KEY `zip` (`zip`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
它包含42486條記錄.
我的查詢,旨在查找第一個表中不在第二個表中的記錄:
SELECT d.*, o.* FROM `dol_msa_zip_assoc` d
LEFT JOIN `v3_msa_zip_assoc` o
ON o.zip = d.zip
WHERE o.zip IS NULL
當我解釋此查詢時,我看到zip列上的索引未被使用:
+----+-------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------------------------+
| 1 | SIMPLE | d | ALL | NULL | NULL | NULL | NULL | 42915 | NULL |
| 1 | SIMPLE | o | ALL | NULL | NULL | NULL | NULL | 42486 | Using where; Not exists; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------------------------+
導致此失敗的原因可能是什么?是因為一個zip列是latin1而另一個是utf8?如何使用此查詢來使用索引,以便它不需要運行年齡?
編輯:反轉JOIN的順序顯然確實利用了索引:
SELECT d . * , o . *
FROM `v3_msa_zip_assoc` o
LEFT JOIN `dol_msa_zip_assoc` d ON d.zip = o.zip
WHERE d.zip IS NULL
這是解釋:
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------------------+
| 1 | SIMPLE | o | ALL | NULL | NULL | NULL | NULL | 42486 | NULL |
| 1 | SIMPLE | d | ref | zip | zip | 17 | func | 1 | Using where; Not exists |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------------------+
編輯2:我已經改變舊表的結構以使用utf8排序規則.現在定義如下:
CREATE TABLE `v3_msa_zip_assoc` (
`pkey` int(5) unsigned NOT NULL AUTO_INCREMENT,
`zip` varchar(9) NOT NULL DEFAULT '',
`pmsa_msa` varchar(6) NOT NULL DEFAULT '',
PRIMARY KEY (`pkey`),
KEY `zip` (`zip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
這似乎解決了這個問題:
mysql> EXPLAIN SELECT d . * , o . *
-> FROM `dol_msa_zip_assoc` d
-> LEFT JOIN `v3_msa_zip_assoc` o ON o.zip = d.zip
-> WHERE o.zip IS NULL;
+----+-------------+-------+------+---------------+------+---------+---------------------+-------+-------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+---------------------+-------+-------------------------+
| 1 | SIMPLE | d | ALL | NULL | NULL | NULL | NULL | 42915 | NULL |
| 1 | SIMPLE | o | ref | zip | zip | 29 | myplan_v4_dev.d.zip | 1 | Using where; Not exists |
+----+-------------+-------+------+---------------+------+---------+---------------------+-------+-------------------------+
總結
以上是生活随笔為你收集整理的mysql连接字段需要索引_mysql – 索引字段上的连接不使用索引的全部內容,希望文章能夠幫你解決所遇到的問題。