《高性能mysql》

BIT

Mysql的BIT有点神。最好不要用BIT存储boolean。因为Mysql是把BIT当作字符串类型,而不是数字类型。在检测BIT(1)的值时,结果是一个包含二进制0或者1的字符串,而不是ASCII码的0或1。然而,在数字上下文的场景中检索时,结果将是位字符串转换成的数字。例如,存储一个值b'00111001'到BIT(8)的列并且检索它,得到的内容是字符吗为57的字符串。也就是ASCII吗为57的字符‘9’。但在数字上下文场景中,得到数字57.

create table bittest (a bit(8));
insert into bittest values(b'00111001');
select a , a+0 from bittest;
# 得到值为9,57

因此,如果要存储boolean值的话,用tinyint。优势是不存在BIT的字符串和数字类型问题,同时tinyint和BIT长度都是一个字节,不存在浪费空间问题。

主键

以前面试的时候被问到过主键的一些问题。主键是唯一的,这个和唯一索引有什么区别,当时可能紧张了吧,忘记了主键是非空的,这个是和唯一索引的区别之一。现在看了书后,又有了更深一些的认识。

  1. 对于MyIsAM引擎而言,主键和唯一索引对比,确实只是多了个非空区别,但是对于InnoDB而言,并不只是这个区别。InnoDB的二级索引的叶子节点,存储的是主键,需要根据主键再去聚簇索引上查该行的全部数据,因此比唯一索引又多了个定位功能。而MyIsAM存储的是行号。另外,这个也解释了为何所有二级索引最后都隐式地包含了个主键。由此,再引申出一点,如果需要在索引后再加字段的话,需要考察下原有的查询时候有用到隐式的主键,而没有用到待加的新字段,这种查询会在索引加新字段后有变慢的可能性。
  2. 我们经常使用自增ID作为主键,可以使InnoDB表在插入数据时可以顺序插入到主键页,主键也就会近似于被顺序的记录填满,避免页分裂和碎片。而如果使用如UUID这类无序的值作为主键的话,会导致数据随机插入,发生页分裂和碎片的情况,最终会导致插入花费时间增多,索引占用硬盘空间增多的情况。
  3. 顺序的主键什么时候会造成更坏的情况?高并发工作负载,在InnoDB中按主键顺序插入可能会造成明显的争用。

索引

  1. 只有当索引的列顺序和order by子句的顺序完全一致,而且所有列的排序方向(倒叙或正序)都一样时,mysql才能够使用索引来对结果做排序。如果查询需要关联多张表,则只有当order by子句引用的字段全部为第一个表时,才能使用索引做排序。order by子句和查询的限制是一样的:需要满足索引的最左前缀的要求。否则,mysql都需要执行排序操作,而无法利用索引排序。有一种情况下order by子句可以不满足索引的最左前缀的要求,那就说前导列为常量时候。如果where子句或者join子句中对这些列指定了常量,就可以弥补索引的不足。这个根据B-tree的结构思考下如何查询就可以想明白了。

分区

  1. crud操作时,分区层都会先打开并锁住所有的底层表,然后确认哪个分区接受这条记录。那么为什么要先锁表再确认分区?先确认分区再只锁一个表不好么?

to be continue……

你可能感兴趣的:(《高性能mysql》)