阅读mysql分区性能文档

This commit is contained in:
asahi
2025-02-10 12:59:53 +08:00
parent 130714fe74
commit f657d2e2ed

View File

@@ -614,3 +614,28 @@ select partition_name, partition_method, subpartition_name, subpartition_method
| p\_beijing | LIST COLUMNS | p\_beijingsp1 | KEY | | p\_beijing | LIST COLUMNS | p\_beijingsp1 | KEY |
| p\_beijing | LIST COLUMNS | p\_beijingsp2 | KEY | | p\_beijing | LIST COLUMNS | p\_beijingsp2 | KEY |
### 分区中的NULL值
mysql允许对null值做分区`mysql数据库中的分区总是视null值小于任何非null的值`,该逻辑`和order by处理null值的逻辑一致`
故而在使用不同的分区类型时对于null值的处理逻辑如下
- 对于range类型分区当插入null值时其会被放在最左侧的分区中
- 对于list类型的分区如果要插入null值必须在分区的`values in (...)`表达式中指定null值否则插入语句将会报错
- hash和key的分区类型将会将null值当作`0`来散列
### 分区和性能
对于OLTP类型的应用使用分区表时应该相当小心因为分区表可能会带来严重的性能问题。
例如对于包含1000w条数据的表`t`,如果包含主键索引`id`和非主键索引`code`,分区和不分区,其性能分析如下
#### 不分区
如果不对表t进行分区那么根据`id`(唯一主键索引)或`code`非unique索引进行查询例如`select * from t where id = xxx``select * from t where code = xxx`可能只会进行2~3次磁盘io1000w数据构成的B+树其层高为2~3
#### 按id进行分区
如果对表`t`按照`id`进行`hash`分区分为10个分区那么
- 对于按`id`进行查找的语句`select * from t where id = xxx`
- 将t按id分为10个区后如果分区均匀那么每个分区数据大概为100w对分区的查询开销大概为2次磁盘io
- 根据`id`的查询只会在一个分区内进行查找故而磁盘io会从3次减少为2次可以提升查询效率
- 对于按`code`进行查找的语句`select * from t where code = xxx`
- 对于按code进行查找的语句需要扫描所有的10个分区每个分区大概需要2次磁盘io故而总共的磁盘io大约为20次
> 在使用分区表时应尽量小心不正确的使用分区将可能会带来大量的io造成性能瓶颈