Mysql 左外部联接在反转联接顺序时不使用键

Mysql 左外部联接在反转联接顺序时不使用键,mysql,left-join,Mysql,Left Join,正如您所看到的,这两个表具有相同的结构,但一个左外部联接使用键,而另一个不使用键,因此在第二种情况下,性能太差。为什么第二个左连接不使用键 mysql> show create table t1; +-------+-------------------------------------------------------------------------------------------------------------------------------------------

正如您所看到的,这两个表具有相同的结构,但一个左外部联接使用键,而另一个不使用键,因此在第二种情况下,性能太差。为什么第二个左连接不使用键

mysql> show create table t1;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                          |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
  `certificateNo` varchar(32) DEFAULT NULL,
  UNIQUE KEY `certificateNo` (`certificateNo`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> show create table t2;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                             |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t2    | CREATE TABLE `t2` (
  `certificateNo` varchar(32) CHARACTER SET utf8 DEFAULT NULL,
  UNIQUE KEY `certificateNo` (`certificateNo`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select count(1) from t1 left outer join t2 on (t1.certificateNo = t2.certificateNo) where t2.certificateNo is null;
+----------+
| count(1) |
+----------+
|    10839 |
+----------+
1 row in set (0.00 sec)

mysql> explain select count(1) from t1 left outer join t2 on (t1.certificateNo = t2.certificateNo) where t2.certificateNo is null;
+----+-------------+-------+-------+---------------+---------------+---------+------+-------+--------------------------+
| id | select_type | table | type  | possible_keys | key           | key_len | ref  | rows  | Extra                    |
+----+-------------+-------+-------+---------------+---------------+---------+------+-------+--------------------------+
|  1 | SIMPLE      | t1    | index | NULL          | certificateNo | 35      | NULL | 35691 | Using index              |
|  1 | SIMPLE      | t2    | ref   | certificateNo | certificateNo | 99      | func |   138 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------------+---------+------+-------+--------------------------+
2 rows in set (0.01 sec)

mysql> explain select count(1) from t2 left outer join t1 on (t1.certificateNo = t2.certificateNo) where t1.certificateNo is null;
+----+-------------+-------+-------+---------------+---------------+---------+------+-------+--------------------------+
| id | select_type | table | type  | possible_keys | key           | key_len | ref  | rows  | Extra                    |
+----+-------------+-------+-------+---------------+---------------+---------+------+-------+--------------------------+
|  1 | SIMPLE      | t2    | index | NULL          | certificateNo | 99      | NULL | 27785 | Using index              |
|  1 | SIMPLE      | t1    | index | NULL          | certificateNo | 35      | NULL | 35691 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------------+---------+------+-------+--------------------------+
2 rows in set (0.00 sec)

mysql> select count(1) from t1 inner join t2  on (t1.certificateNo = t2.certificateNo) ;
+----------+
| count(1) |
+----------+
|    21603 |
+----------+
1 row in set (0.16 sec)

mysql> select count(1) from t1;
+----------+
| count(1) |
+----------+
|    32442 |
+----------+
1 row in set (0.01 sec)

mysql> select count(1) from t2;
+----------+
| count(1) |
+----------+
|    26837 |
+----------+
1 row in set (0.01 sec)

两个表中的字符集不同。是的。测试。如果它们有相同的字符集,那么在任何情况下都会使用ref。Good catch@Barmar,我只在CREATE TABLE语法的末尾看到了字符集。为了更进一步,我建议将未签名的int列添加到两个表中,并在这些表上进行连接,而不是在varchar列上进行连接。@Barmar是的,我在发布之前就注意到了:-但它仍然不能解释为什么在一种情况下使用键而在另一种情况下不使用键。这一定与它是否可以转换字符集并在索引中搜索它有关。显然,这只是一种方式,而不是另一种方式。