1.这两种日志有以下三点不同。redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
2.redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑。
3.redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
为了保证数据库的一致性,必须要保证2份日志一致,因此使用的两阶段式提交。
SQL 标准的事务隔离级别包括:读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(serializable )。
在 InnoDB 中,表都是根据主键顺序以索引的形式存放的,这种存储方式的表称为索引组织表。又因为前面我们提到的,InnoDB 使用了 B+ 树索引模型,所以数据都是存储在 B+ 树中的。
根据叶子节点的内容,索引类型分为主键索引和非主键索引。主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引(clustered index)。非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)。
覆盖索引、最左前缀原则、索引下推
MySQL 里面表级别的锁有两种:一种是表锁,一种是元数据锁(meta data lock,MDL)。
MDL 不需要显式使用,在访问一个表的时候会被自动加上。MDL 的作用是,保证读写的正确性在 MySQL 5.5 版本中引入了 MDL,当对一个表做增删改查操作的时候,加 MDL 读锁;当要对表做结构变更操作的时候,加 MDL 写锁。
普通索引和唯一索引应该怎么选择?
其实,这两类索引在查询能力上是没差别的,主要考虑的是对更新性能的影响。实际使用中,普通索引和 change buffer 的配合使用,对于数据量大的表的更新优化还是很明显的。
索引选择异常和处理:
对于由于索引统计信息不准确导致的问题,可以用 analyze table 来解决。
而对于其他优化器误判的情况:
1.采用 force index 强行选择一个索引。
2.考虑修改语句,引导 MySQL 使用我们期望的索引。
3.在有些场景下,可以新建一个更合适的索引,来提供给优化器做选择,或删掉误用的索引。
1.使用前缀索引,定义好长度,就可以做到既节省空间,又不用额外增加太多的查询成本。但使用前缀索引就无法使用覆盖索引对查询性能的优化,这也是在选择是否使用前缀索引时需要考虑的一个因素。
2.总结:
一个 InnoDB 表包含两部分,即:表结构定义和数据。表结构定义占用的空间很小,主要考虑表数据的空间回收。
表数据既可以存在共享表空间里,也可以是单独的文件。这个行为是由参数 innodb_file_per_table 控制的:
这个参数设置为 OFF 表示的是,表的数据放在系统共享表空间,也就是跟数据字典放在一起;
这个参数设置为 ON 表示的是,每个 InnoDB 表数据存储在一个以 .ibd 为后缀的文件中。
从 MySQL 5.6.6 版本开始,它的默认值就是 ON 了。我建议你不论使用 MySQL 的哪个版本,都将这个值设置为 ON。因为,一个表单独存储为一个文件更容易管理,而且在你不需要这个表的时候,通过 drop table 命令,系统就会直接删除这个文件。而如果是放在共享表空间中,即使表删掉了,空间也是不会回收的。
如果要收缩一个表,只是 delete 掉表里面不用的数据的话,表文件的大小是不会变的,还要通过 alter table 命令重建表,才能达到表文件变小的目的。
count(*)、count(主键 id) 和 count(1) 都表示返回满足条件的结果集的总行数;而 count(字段),则表示返回满足条件的数据行里面,参数“字段”不为 NULL 的总个数。
如果直接使用 order by rand(),这个语句需要 Using temporary 和 Using filesort,查询的执行代价往往是比较大的。所以,在设计的时候你要尽量避开这种写法。在实际应用的过程中,比较规范的用法就是:尽量将业务逻辑写在业务代码中,让数据库只做“读写数据”的事情。
对索引字段做函数操作,可能会破坏索引值的有序性,因此优化器就决定放弃走树搜索功能。同时,隐式类型转换,隐式字符编码转换,也会要求在索引字段上做函数操作而导致了全索引扫描。
一种是 statement,一种是 row。还有一种 mixed,其实它就是前两种格式的混合。
当 binlog_format=statement 时,binlog 里面记录的就是 SQL 语句的原文。
当 binlog_format 使用 row 格式的时候,binlog 里面记录了真实修改行的数据。
因为有些 statement 格式的 binlog 可能会导致主备不一致,所以要使用 row 格式。但 row 格式的缺点是,很占空间。比如你用一个 delete 语句删掉 10 万行数据,用 statement 的话就是一个 SQL 语句被记录到 binlog 中,占用几十个字节的空间。但如果用 row 格式的 binlog,就要把这 10 万条记录都写到 binlog 中。这样做,不仅会占用更大的空间,同时写 binlog 也要耗费 IO 资源,影响执行速度。所以,MySQL 就取了个折中方案,也就是有了 mixed 格式的 binlog。mixed 格式的意思是,MySQL 自己会判断这条 SQL 语句是否可能引起主备不一致,如果有可能,就用 row 格式,否则就用 statement 格式。也就是说,mixed 格式可以利用 statment 格式的优点,同时又避免了数据不一致的风险。