1、背景
mysql通过查询条件查询到结果的过程就叫访问方法,一条查询语句的访问方法有很多种,接下来我们就来讲一下各种访问方法。
2、环境
创建表:
mysql> create table test2
-> (
-> id int auto_increment primary key,
-> str1 varchar(255),
-> str2 varchar(255),
-> str3 char(5),
-> str4 varchar(255),
-> str5 char(10),
-> index idx_str1 (str1),
-> unique index idx_str3 (str3),
-> index idx_str4_str5 (str4, str5)
-> ) engine = innodb default charset = utf8;
query ok, 0 rows affected, 1 warning (0.03 sec)
插入100条数据:
mysql> insert into test2 (str1, str2, str3, str4, str5) values
-> ('value1', 'data1', 'abc', 'value4_1', 'value5_1'),
-> ('value2', 'data2', 'def', 'value4_2', 'value5_2'),
-> ...
-> ('value99', 'data99', 'yz91', 'value4_99', 'value5_99'),
-> ('value100', 'data100', 'yz92', 'value4_100', 'value5_100');
query ok, 100 rows affected (0.02 sec)
records: 100 duplicates: 0 warnings: 0
3、访问类型
【1】const
通过主键索引或者唯一索引查询一条记录的方法就为const,可以通过explain关键字来看查询语句的访问方式,通过主键查询示例:
mysql> explain select * from test2 where id = 3; +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | simple | test2 | null | const | primary | primary | 4 | const | 1 | 100.00 | null | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec)
type字段就是访问方式,我们再看看通过唯一索引查询的示例:
mysql> explain select * from test2 where str3 = 'abc'; +----+-------------+-------+------------+-------+---------------+----------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra | +----+-------------+-------+------------+-------+---------------+----------+---------+-------+------+----------+-------+ | 1 | simple | test2 | null | const | idx_str3 | idx_str3 | 16 | const | 1 | 100.00 | null | +----+-------------+-------+------------+-------+---------------+----------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec)
【2】ref
使用普通二级索引进行等值匹配时,访问类型就为ref,示例如下:
mysql> explain select * from test2 where str1 = 'value7'; +----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra | +----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+ | 1 | simple | test2 | null | ref | idx_str1 | idx_str1 | 767 | const | 1 | 100.00 | null | +----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.01 sec)
【3】ref_or_null
二级索引进行等值匹配时,又想把值为null的查询出来,这种查询类型就为ref_or_null,先把上面插入的数据部分记录的str1字段改为null,sql如下:
mysql> update test2 set str1 = null where id in (3, 6, 8, 9, 34, 78, 89); query ok, 7 rows affected (0.01 sec) rows matched: 7 changed: 7 warnings: 0
再看查询类型:
mysql> explain select * from test2 where str1 = 'value7' or str1 = null;
+----+-------------+-------+------------+-------------+---------------+----------+---------+-------+------+----------+--------
---------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra
|
+----+-------------+-------+------------+-------------+---------------+----------+---------+-------+------+----------+--------
---------------+
| 1 | simple | test2 | null | ref_or_null | idx_str1 | idx_str1 | 768 | const | 2 | 100.00 | using i
ndex condition |
+----+-------------+-------+------------+-------------+---------------+----------+---------+-------+------+----------+--------
---------------+
1 row in set, 1 warning (0.00 sec)
【4】range
顾名思义范围查询就是range,示例如下:
mysql> explain select * from test2 where id > 2 and id < 7; +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | 1 | simple | test2 | null | range | primary | primary | 4 | null | 4 | 100.00 | using where | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec)
【5】index
使用组合索引中非最左边作为查询条件时,并且查询的字段不需要回表,这个时候就会将组合索引叶子节点全部扫描一遍,这种查询方式就叫index,示例如下:
mysql> explain select str4, str5 from test2 where str5 = 'value5_15';
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+----------
----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra
|
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+----------
----------------+
| 1 | simple | test2 | null | index | idx_str4_str5 | idx_str4_str5 | 799 | null | 100 | 10.00 | using whe
re; using index |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+----------
----------------+
1 row in set, 1 warning (0.00 sec)
【6】all
对主键索引所在的叶子节点进行全表扫描就叫all,示例如下:
mysql> explain select * from test2; +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+ | 1 | simple | test2 | null | all | null | null | null | null | 100 | 100.00 | null | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec)
4、总结
mysql中优化器会将我们的查询条件进行优化,我们可以通过explain关键字来查看单表查询的访问方式。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论