我们来学mysql -- 访问方法
- 题记
- 准备
- 访问方式
- const
- ref
- index
- range
- all
- 小结
题记
- 前面提到索引的生成和索引的使用
- 十一国庆自驾去景区,地图规划了多条路线,有的红绿灯多,有的距离远,有的收费站多,你自己决定
- 说回查询语句,本质只是一种声明式语法,通过何种方式查到结果,在mysql中这种方式称为访问方法,由mysql决定
- 与选择路线相同,同一种查询语句可以使用不同的访问方法
准备
- 创建ucoding表,交由GPT写提供插入记录的存储过程
CREATE TABLE `test`.`ucoding` (`id` int(0) NOT NULL AUTO_INCREMENT,`k1` varchar(100) NULL,`k2` int(0) NULL,`k3` varchar(100) NULL,`k_part1` varchar(100) NULL,`k_part2` varchar(100) NULL,`k_part3` varchar(100) NULL,`mark` varchar(100) NULL,PRIMARY KEY (`id`),INDEX `idx_key1`(`k1`),INDEX `uk_key2`(`k2`),INDEX `idx_key3`(`k3`),INDEX `idx_key_part`(`k_part1`, `k_part2`, `k_part3`)
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8;
CREATE DEFINER=`root`@`localhost` PROCEDURE `AutoGen`(IN rowCount INT)
BEGINDECLARE counter INT DEFAULT 1;WHILE counter <= rowCount DO-- 生成随机数据SET @key1 = CONCAT(CHAR(FLOOR(RAND() * 26) + 65), SUBSTRING(MD5(RAND()), 1, 4));SET @key2 = counter;SET @key3 = CONCAT(CHAR(FLOOR(RAND() * 26) + 65), LPAD(counter, 5, '0'));SET @key_part1 = CONCAT('part1_', counter);SET @key_part2 = CONCAT('part2_', counter);SET @key_part3 = CONCAT('part3_', counter);SET @common_field = CONCAT('common_', counter);-- 插入数据的逻辑INSERT INTO ucoding (k1, k2, k3, k_part1, k_part2, k_part3, mark)VALUES (@key1, @key2, @key3, @key_part1, @key_part2, @key_part3, @common_field);SET counter = counter + 1;END WHILE;
END
访问方式
const
select * from ucoding where id = 300
- 通过主键或唯一二级索引与常数的等值比较定位一条记录是飞快的,称为const访问方法(意思是常数级别,代价可以忽略不计)
ref
select * from ucoding where k1 = ccd
- 普通二级索引列与常数进行等值比较
- 由于普通二级索引不限制索引列值的唯一性,可能有多条记录
- 如果是单点扫描区间1,回表代价低,称为ref访问方法
index
select k_part1,k_part2 ,k_part3 from ucoding where k_part2 = 'abc'
- 按照联合索引使用要求,sql条件不满足最左原则,不走idx_key_part索引,事实却非如此
- 这又是为什么呢?
- 查询列表只有k_part1、k_part2、k_part3,而索引idx_key_part又包含这3列
- 条件只有k_part2,包含在idx_key_part中
- 那便是,可以通过遍历idx_key_part索引的所有二级记录,针对每条记录如果
k_part2 = 'abc'
成立,则发给客户端 ,不用回表 - 所以把扫描全部二级索引且不回表称为index访问方法
- 但凡查询列加上其他字段,需要回表,则不满足
range
select * from ucoding where k2 in (1233,1566) or (k2 >=32 and k2<=67)
- 如果使用idx_key2执行查询(走这个索引),对应的扫描区间是[1233,1233] 、[1566,1566] 以及 (32,67]
-形成若干个单点扫描区间或范围扫描区间称为range访问方法
all
- 直接查询全表扫描,便是all访问方法
小结
- 想必各位看官已经明白了,访问方法就是explian执行计划中type字段的值
- 通过type值便知道查询是否走了索引,一定程度上知道了查询性能
关于扫描区间,参考 使用索引 ↩︎