mysql join table associated self-energizing + id

join wording

  • If left join the table on the left must be driven form? Equivalent match join two tables contain multiple conditions, must write on or just put on a written, wrote that where the rest part?

    create    table   a(f1    int,    f2  int,    index(f1))engine=innodb;
    2 create  table   b(f1    int,    f2  int)engine=innodb;
    3 insert  into    a   values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6);
    4 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*/
    2 select  *   from    a   left    join    b   on(a.f1=b.f1)   where   (a.f2=b.f2);/*Q2*/

    Results of the:

Since no index table b, using Block Nexted Loop Join (BNL) Algorithm

  1. A table of contents reads join_buffer because select *, so the fields f1, f2 have been placed
  2. B-sequential scanning, for each row of data, it is determined join condition is satisfied, the recording condition satisfied, as a row of the result set, if the where clause, where portion determination condition is satisfied and then return.
  3. After completion of the scan table b, there is no match for a row of a table, with null fill, into the result set.

Q2 statement, explain the results:

b is the driving table, if a statement is nothing EXTRA field, then, is the Index Nested_Loop Join algorithm, so the process is:

  1. B-sequential scanning, each line with a b.f1 go to check, whether the matching a.f2 = b.f2 satisfied, returned as a result set.

Differences Q1 and Q2 flow of execution because the query optimizer based on Q2 semantic optimized: in mysql in, the results null equivalence judgment and judgment is not equivalent with any null value, including select null = null returns null.

In Q2, where a.f2 = b.f2 said b.f2 not contain the query result is null line, so that the same is to find the semantic left join two row table corresponding to f1 f2, if the presence of a b not match, give up. The optimizer put the statement left join rewriting became join, because of a f1 indexed, put b as the driving table, so you can use NLJ algorithm, so use the left join, the left side of the table is not necessarily the driving table .

If you need to left join semantic field can not be driven on the table where conditions do the equivalent in judgment or judgment is not equivalent, it must be written on the inside.

Nested Loop Join performance issues

  • Algorithm execution logic BLN
    1. Driving data table read into the join_buffer, which is unordered array.
    2. 顺序遍历被驱动表的所有行,每一行都跟join_buffer做匹配,成功则作为结果集的一部分返回。
  • 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个字节。所以:

  1. row_id写入表的范围是0到2^48-1;
  2. 当达到最大时,如果再有插入数据的行为来申请row_id,拿到以后再去最后6个字节就是0,然后继续循环。
  3. 再innodb的逻辑里,达到最大后循环,新数据会覆盖已经存在的数据。

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

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  {
2       new_id= thread_id_counter++;
3 } while   (!thread_ids.insert_unique(new_id).second);

Guess you like

Origin www.cnblogs.com/jimmyhe/p/11245304.html