我们来学mysql -- 访问方法(原理篇)

我们来学mysql -- 访问方法

题记

  • 前面提到索引的生成和索引的使用
  • 十一国庆自驾去景区,地图规划了多条路线,有的红绿灯多,有的距离远,有的收费站多,你自己决定
  • 说回查询语句,本质只是一种声明式语法,通过何种方式查到结果,在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)
BEGIN
    DECLARE 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值便知道查询是否走了索引,一定程度上知道了查询性能

  1. 关于扫描区间,参考 使用索引 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UCoding

说话好听~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值