单表访问方法

访问方法

MySQL把执行查询语句的方式称为访问方法

const

通过索引定位一条记录

select * from single_table where id = 1438;

通过唯一二级索引列来定位一条记录

select * from single_table where key3 = 1438;

查询步骤:

  • 在uk_key3对应的B+树索引中,根据key3列与常熟的等值比较条件定位到一条二级索引记录
  • 然后根据该记录的id值到聚簇索引中获取到完整的用户记录。

ref

使用普通的二级索引与常熟进行等值比较

select * form single_table where key1 = 'abc';

对于这样的查询,可以进行全表扫描也可以通过二级索引idx_key1来执行,由于查询的是* ,所以每当使用二级索引查询出一条数据时,都需要进行回表处理,所以ref比const消耗的成本高一点。

  • 对存在null值的列时,最多只能用到ref的查询语句,而不能使用const查询语句。
  • 对于复合索引来说,只要最左边连续的列是余常熟进行等值比较,就可以使用ref进项查询。

ref_or_null

我们不仅想找出某个二级索引列的值等于某个常数的记录,而且还想把该列中的值为NULL的记录也找出来

select * from single_table where key1='a' or key1 is null;

range

对索引列进行区间扫描

select * from single_table where key3 in (1,4,5) or key3 in(9,10);

index

扫描全部二级索引的访问方法并且不需要进行回表操作。key_part2并不是联合索引idx_key_part的索引列中最右边的列,所以无法形成适合的范围区间来减少需要扫描的记录数量,从而无法使用ref和range访问方法来执行这个语句,但是这个查询语句复合:

  • 查询列只有idx_key_part中的列
  • 只有key_part2列,这个列也包含在索引idx_key_part中
    由于二级索引记录要比聚簇索引记录小的多,所以整个过程不需要回表操作。
select key_part1, key_part2, key_part3 from single_table where key_part2 = 'abc';

all

全表扫描

索引合并

使用多个二级索引完成一次查询

select * from single_table where idx_key1='a' and idx_key2='b';

从每个索引中获取到的所及索引记录按照主键值排序(为了更加快速获取交集),在从多个索引中获取交集,并执行回表操作。

Union索引合并

从不同索引中扫描到的记录的id值取并集,为这些id值执行回表操作。

select * from single_table where key1 = 'a' OR key2 = 'b';

上面的查询,在idx_key1的[‘a’,‘a’]扫描区间中的二级索引记录都是按照主键值排序的,在idx_key3的[‘b’,‘b’]扫描区间中的二级索引记录也都是按照主键值排序的。

  • 从两个有序集合中执行去重操作
  • id有序,在执行回表操作的时候就不会进行随机I/O。
    以下SQL不能使用UNION索引
select * from single_table where key1 = 'a' or key3 = 'b';

以下sql也可以使用Union索引

select * from single_table where key1 = 'a' or id > 9000
select * from single_table where (key_part1 = 'a' and key_part2='b' and key_part3='c') OR (key1 = 'b' and key3 = 'b');

Sort-Union索引合并

先将各个索引中扫描的记录的主键进行排序,在按照执行Union索引合并的方式执行查询。

select * from single_table where key1 < 'a' OR key3 > 'z';

将从各个索引中扫描到的记录的主键值进行排序,再按照执行Union索引合并进行查询。

测试数据

CREATE TABLE `single_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `key1` varchar(10) DEFAULT NULL,
  `key2` varchar(10) DEFAULT NULL,
  `key3` int(10) DEFAULT NOT NULL,
  `com_key1` varchar(10) DEFAULT NULL,
  `com_key2` varchar(10) DEFAULT NULL,
  `com_key3` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_key1` (`key1`) USING BTREE,
  KEY `idx_key2` (`key2`) USING BTREE,
  UNIQUE KEY uk_key3 (`key3`) USING BTREE,
  KEY `idx_com` (`com_key1`,`com_key2`, `com_key3`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8;
CREATE FUNCTION `rand_str_func`(`n` int) RETURNS varchar(255) 
BEGIN
	#Routine body goes here...
  declare str varchar(255) default 'abcdefghijklmnopqrstuvwxyz';
  declare num int default 0;
  declare return_str varchar(255) default '';
  while num<n DO
     set return_str= concat(return_str,substr(str,floor(RAND()*26)+1,1));
     set num=num+1;
  end while;
  return return_str;
END
CREATE  PROCEDURE `rand_insert`(in n int)
BEGIN
	#Routine body goes here...
   DECLARE num int default 0;
   a:REPEAT 
    insert into single_table values(0,rand_str_func(1),rand_str_func(1),num,rand_str_func(1),rand_str_func(1),rand_str_func(1));
    set num=num+1;
   until num>=n end repeat a;
END
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值