1.MySQL解决幻读问题
MySQL InnoDB通过版本号解决事务的幻读问题
a.select情况:
InnoDB只会查找版本高于当前事务版本的数据行(即行的系统版本小于或等于事务的系统版本号),这样确保了事务读取的行是当前事务开始之前已经存在的行,或者是事务自己自身插入或者修改的行。
b.insert情况:
InnoDB为新插入的每一行记录保存当前系统的版本号作为行版本号。
c.delete情况:
InnoDB为删除的每一行记录保存当前系统的版本号作为行删除标示。
d.update情况:
InnoDB为新插入的每一行记录保存当前系统的版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标示。
2.MySQL不走索引的情况
1.使用like '%abc';
2.where 中的or不是所有字段都是索引字段;
3.组合索引,不包含第一个字段的查询;
4.子查询中order by的索引会失效,同时可能导致子查询中的where条件索引都不能用;
5.列类型为字符串类型,查询时没有用单引号引起来;
6.在where查询语句中使用表达式或者函数;
7.在where查询语句中对字段进行NULL值判断;
8.DATE_FORMAT()格式化时间,格式化后的时间再去比较,可能会导致索引失效。
3.B+树的优点
1.从根节点到叶子节点的搜索效率基本相同,不会出现大幅波动;
2.方便顺序扫描,只需要遍历所有叶子节点即可;
3.磁盘读写代价低,因为非叶子节点不保存行数据,同一个数据块,非叶子节点保存的关键字数据量比B树要高很多,因此一次读入的关键字也就越多,降低了IO次数;
4.B+树支持范围查询,而B树对范围查询支持性很差。
4.MySQL自增主键
优点:
1.插入效率高,每次插入新的记录,记录会顺序的添加到当前索引节点的后续位置,当前页写满后,自动开辟新的一页;
2.节省索引存储空间,技术是UUID的两倍;
3.使用UUID(Universally Unique Identifier)主键的时候,每次插入主键时,插入的索引中的位置几乎随机,会导致非叶子节点的分裂,MySQL不得不为了插入新纪录而移动数据,,甚至导致磁盘IO和不饱和的节点,造成大量的碎片,甚至触发optimize table重建表来优化。
缺点:
1.不适合分表、分库和分布式的场景。这些场景只能牺牲性能,使用UUID,但是UUID适合小规模的分布式环境,不适合大规模的分布式环境,特别数据量大时,UUID带来的读写性能的下降很厉害。
Twitter为解决分布式自增ID的问题,给出了snowflake雪花算法来实现全局自增ID,这样ID的生成不依赖于DB,而是依赖于内存,高性能高可用。但是snowflake算法依赖于系统时钟的一致性,如果机器的时钟回拨,可能会导致ID冲突。
网友评论