Skip to content

Commit

Permalink
add DatabaseOptimization.md #1
Browse files Browse the repository at this point in the history
  • Loading branch information
wanglekai committed Jan 9, 2021
1 parent 7099b4a commit 90725b7
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions DatabaseOptimization.md
Original file line number Diff line number Diff line change
@@ -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 速度,这个速度损耗可以忽略,但提高查找速度是明显的。另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。
- 创建索引时避免以下错误观念:
- 索引越多越好,认为需要一个查询就建一个索引。
- 宁缺勿滥,认为索引会消耗空间、严重拖慢更新和新增速度。
- 抵制惟一索引,认为业务的惟一性一律需要在应用层通过“先查后插”方式解决。
- 过早优化,在不了解系统的情况下就开始优化。

0 comments on commit 90725b7

Please sign in to comment.