• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Mysql join联表及id自增实例解析

    join的写法

    如果用left join 左边的表一定是驱动表吗?两个表的join包含多个条件的等值匹配,都要写道on还是只把一个写到on,其余写道where部分?

    create	table	a(f1	int,	f2	int,	index(f1))engine=innodb;
     create	table	b(f1	int,	f2	int)engine=innodb;
     insert	into	a	values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6);
     insert	into	b	values(3,3),(4,4),(5,5),(6,6),(7,7),(8,8);
    select	*	from	a	left	join	b	on(a.f1=b.f1)	and	(a.f2=b.f2);	/*Q1*/
     select	*	from	a	left	join	b	on(a.f1=b.f1)	where	(a.f2=b.f2);/*Q2*/

    执行结果:

    由于表b没有索引,使用的是Block Nexted Loop Join(BNL)算法

    Q2语句中,explain结果:

    b为驱动表,如果一条语句EXTRA字段什么都没有的话,就是Index Nested_Loop Join算法,因此流程是:

    顺序扫描b,每一行用b.f1到a中去查,匹配a.f2=b.f2是否满足,作为结果集返回。

    Q1与Q2执行流程的差异是因为优化器基于Q2这个查询语义做了优化:在mysql里,null跟任何值执行等值判断和不等值判断的结果都是null,包括select null = null 也返回null。

    在Q2中,where a.f2 = b.f2表示,查询结果里不会包含b.f2是null的行,这样left join语义就是找到两个表里f1 f2对应相同的行,如果a存在而b匹配不到,就放弃。因此优化器把这条语句的left join改写成了join,因为a的f1有索引,就把b作为驱动表,这样可以用NLJ算法,所以在使用left join时,左边的表不一定是驱动表。

    如果需要left join的语义,就不能把被驱动表的字段放在where条件里做等值判断或不等值判断,必须写在on里面。

    Nested Loop Join的性能问题

    BLN算法的执行逻辑

    Simple Nested Loop Join算法逻辑是:顺序去除驱动表的每一行数据,到被驱动表做全表匹配。

    两者差异:

    在对被驱动表做全表扫描时,如果数据没有在buffer pool中,需要等待部分数据从磁盘读入。会影响正常业务的buffer pool命中率,而且会对被驱动表做多次访问,更容易将这些数据页放到buffer pool头部。所以BNL算法性能会更好。自增id

    mysql中自增id定义了初始值,不停的增长,但是有上限,2^32-1,自增的id用完了会怎么样呢。

    表定义的自增值达到上限后,再申请下一个id时,得到的值保持不变。再次插入时会报主键冲突错误。所以在建表时,如果有频繁的增删改时,就应该创建8个字节的bigint unsigned。

    innodb 系统自增row_id

    如果创建了Innodb表没有指定主键,那么innodb会创建一个不可见的,长度为6个字节的row_id,所有无主键的innodb表,每插入一行数据,都将当前的dict_sys.row_id值作为要插入数据的row_id,然后自增1。

    实际上,代码实现时,row_id是一个长度为8字节的无符号长整形,但是innodb在设计时,给row_id只是6个字节的长度,这样写道数据时只放了最后6个字节。所以:

    从这个角度看,我们应该主动创建自增主键,这样达到上限后,插入数据会报错。数据的可靠性会更加有保障。

    XID

    redo log 和 binlog相互配合的时候,它们有一个共同的字段就是xid,在mysql中对应事务的。xid最大时2^64次方,用尽只存在理论。

    thread_id

    系统保存了全局变量thread_id_counter,每新建一个连接,就将thread_id_counter赋值给这个新连接的线程变量。thread_id_counter定义的大小是4个字节,因此到2^32-1就会重置为0,然后继续增加。但是show processlist里不会看到两个相同的thread_id,这是因为mysql设计了一个唯一数组逻辑,给新线程分配thread_id的时候:

    do	{
     		new_id=	thread_id_counter++;
     }	while	(!thread_ids.insert_unique(new_id).second);

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    您可能感兴趣的文章:
    • Mysql自增主键id不是以此逐级递增的处理
    • Mysql主键UUID和自增主键的区别及优劣分析
    • 详解mysql插入数据后返回自增ID的七种方法
    • MySQL的自增ID(主键) 用完了的解决方法
    • 关于mysql自增id,你需要知道的
    • MySQL表自增id溢出的故障复盘解决
    • 关于MySQL自增ID的一些小问题总结
    • mysql id从1开始自增 快速解决id不连续的问题
    上一篇:MySQL 如何修改root用户的密码
    下一篇:Mysql临时表及分区表区别详解
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Mysql join联表及id自增实例解析 Mysql,join,联表,及,自增,实例,