都会造成索引失效。原因在于查询的结果可能是多个,不知道从哪个索引值开始
比较,于是就只能通过全表扫描的方式来查询。
对索引进行函数/对索引进行表达式计算,因为索引保持的是索引字段的原始值,
而不是经过函数计算的值,自然就没办法走索引。
对索引进行隐式转换相当于使用了新函数。
WHERE 子句中的 OR 语句,只要有条件列不是索引列,就会进行全表扫描。
10、字符串加索引
直接创建完整索引,这样可能会比较占用空间。
创建前缀索引,节省空间,但会增加查询扫描次数,并且不能使用覆盖索引。
倒序存储,再创建前缀索引,用于绕过字符串本身前缀的区分度不够的问题。
创建 hash 字段索引,查询性能稳定,有额外的存储和计算消耗,跟第三种方式
一样,都不支持范围扫描。
日志相关
11、MySQL 的 change buffer 是什么?
当需要更新一个数据页时,如果数据页在内存中就直接更新;而如果这个数据页
还没有在内存中的话,在不影响数据一致性的前提下,InnoDB 会将这些更新操
作缓存在 change buffer 中。
这样就不需要从磁盘中读入这个数据页了,在下次查询需要访问这个数据页的时
候,将数据页读入内存,然后执行 change buffer 中与这个页有关的操作。通过
这种方式就能保证这个数据逻辑的正确性。
注意唯一索引的更新就不能使用 change buffer,实际上也只有普通索引可以使
用。
适用场景:
- 对于写多读少的业务来说,页面在写完以后马上被访问到的概率比较小,此时
change buffer 的使用效果最好。这种业务模型常见的就是账单类、日志类的系
统。
- 反过来,假设一个业务的更新模式是写入之后马上会做查询,那么即使满足了
条件,将更新先记录在 change buffer,但之后由于马上要访问这个数据页,会
立即触发 merge 过程。这样随机访问 IO 的次数不会减少,反而增加了 change
buffer 的维护代价。
12、MySQL 是如何判断一行扫描数的?
MySQL 在真正开始执行语句之前,并不能精确地知道满足这个条件的记录有多
少条。
而只能根据统计信息来估算记录数。这个统计信息就是索引的“区分度。
13、MySQL 的 redo log 和 binlog 区别?
14、为什么需要 redo log?
redo log 主要用于 MySQL 异常重启后的一种数据恢复手段,确保了数据的一致
性。