diff --git a/DatabaseOptimization.md b/DatabaseOptimization.md new file mode 100644 index 0000000..a27046a --- /dev/null +++ b/DatabaseOptimization.md @@ -0,0 +1,50 @@ +# database optimization notes +Just personal notes for my own convenience. + +## 索引优化规则 + +- like 语句的前导模糊查询不能使用索引。 +- union、in、or 都能够命中索引,建议使用 in。 + - union 能够命中索引,并且 MySQL 耗费的 CPU 最少。 + - `in` 能够命中索引,查询优化耗费的 CPU 比 `union all` 多,但可以忽略不计,一般情况下建议使用 in。、 + - `or` 新版的 MySQL 能够命中索引,查询优化耗费的 CPU 比 `in` 多,不建议频繁用 `or`。 + - 有些地方说在 `where` 条件中使用 `or`,索引会失效,造成全表扫描,这是个误区: + - 要求 `where` 子句使用的所有字段,都必须建立索引。 + - 如果数据量太少,mysql 制定执行计划时发现全表扫描比索引查找更快,所以会不使用索引。 + - 确保 mysql 版本 5.0 以上,且查询优化器开启了 `index_merge_union = on`, 也就是变量 `optimizer_switch` 里存在 `index_merge_union` 且为 `on`。 +- 负向条件查询不能使用索引。 + - 负向条件有:`!=、<>、not in、not exists、not like` 等。 +- 联合索引最左前缀原则。 + - 建立联合索引的时候,区分度最高的字段在最左边。 + - 存在非等号和等号混合判断条件时,在建立索引时,把等号条件的列前置。如 `where a>? and b=?`,那么即使 `a` 的区分度更高,也必须把 `b` 放在索引的最前列。 + - 最左前缀查询时,并不是指 SQL 语句的 where 顺序要和联合索引一致。 +- 不能使用索引中范围条件右边的列(范围列可以用到索引),范围列之后列的索引全失效。 + - 范围条件有:`<、<=、>、>=、between` 等。 + - 索引最多用于一个范围列,如果查询条件中有两个范围列则无法全用到索引。 + - 假如有联合索引 `(empno、title、fromdate)`,那么下面的 SQL 中 `emp_no` 可以用到索引,而 `title` 和 `from_date` 则使用不到索引。 +- 不要在索引列上面做任何操作(计算、函数),否则会导致索引失效而转向全表扫描。 +- 强制类型转换会全表扫描。 + - 字符串类型不加单引号会导致索引失效,因为mysql会自己做类型转换,相当于在索引列上进行了操作。 +- 更新十分频繁、数据区分度不高的列不宜建立索引。 + - 更新会变更 B+ 树,更新频繁的字段建立索引会大大降低数据库性能。 + - “性别”这种区分度不大的属性,建立索引是没有什么意义的,不能有效过滤数据,性能与全表扫描类似。 + - 一般区分度在80%以上的时候就可以建立索引,区分度可以使用 `count(distinct(列名))/count(*)` 来计算。 +- 利用覆盖索引来进行查询操作,避免回表,减少 `select *` 的使用。 +- 索引不会包含有NULL值的列。 + - 只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时,尽量使用not null 约束以及默认值。 +- is null, is not null 无法使用索引。 +- 如果有 order by、group by 的场景,请注意利用索引的有序性。 +- 使用短索引(前缀索引)。 +- 利用延迟关联或者子查询优化超多分页场景。 +- 如果明确知道只有一条结果返回,limit 1 能够提高效率。 +- 超过三个表最好不要 join。 +- 单表索引建议控制在5个以内。 +- SQL 性能优化 explain 中的 type:至少要达到 range 级别,要求是 ref 级别,如果可以是 consts 最好。 +- 业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。 + - 不要以为唯一索引影响了 insert 速度,这个速度损耗可以忽略,但提高查找速度是明显的。另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。 +- 创建索引时避免以下错误观念: + - 索引越多越好,认为需要一个查询就建一个索引。 + - 宁缺勿滥,认为索引会消耗空间、严重拖慢更新和新增速度。 + - 抵制惟一索引,认为业务的惟一性一律需要在应用层通过“先查后插”方式解决。 + - 过早优化,在不了解系统的情况下就开始优化。 + \ No newline at end of file