1.1 单表unique查询
select * from nkeys where c3 = 3;
调用流程:
mysql_execute_command -> handle_select -> mysql_select -> JOIN_optimize -> make_join_statistics ->
if ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME) ->
若当前索引为unique索引,同时
if (const_ref == eq_part) ->
指定的等值条件与当前索引的unique key一致
s->type = JT_CONST ->
当前表上的查询,返回的数据量是一个常量
join_read_const_table -> … -> row0sel.c::row_search_for_mysql ->
调用底层函数,做一次unique scan,主要功能是保证explain的正确性。有这个必要吗?看下面的explain截图,就可以发现此函数的功能:

if (s->type == JT_SYSTEM || s->type == JT_CONST) ->
s->found_records = s->records = s->read_time = 1; s->worst_seeks = 1.0;
JT_CONST情况下,查询一定只返回1条数据,不需要调用ha_innobase::records_in_range函数进行判断。
if (join->const_tables != join_tables)
choose_plan();
若当前不全是TL_CONST查询,还需要调用choose_plan函数,判断非const表的最优执行路径。单表情况下,只需要计算全表扫描代价;多表join条件下,需要计算各非const表的join顺序以及单表的最优路径。TL_CONST情况下,不需要调用choose_plan(单表查询情况下)。
1.1.1 单表Unique查询总结
mysql查询优化,对于unique查询做了路径优化,并不需要调用底层提供的records_in_range函数判断查询的代价;同时也不需要调用choose_plan函数,确定此查询全表扫描代价(单表情况下)。
只要指定了unique key上的等值查询,那么无论后面还有多少其他查询条件,mysql查询优化一定会选择unique key索引,做unique查询,如下:

查询优化仍旧选择c3 unique索引,而非选择nkey1索引,虽然nkey1上有c3,c5两列。
本系列文章主目录:MySQL数据库InnoDB存储引擎查询优化器实现的分析