1. 首页 > 国产数据库教程 > TiDB教程 > 正文

tidb教程FG018-TiDB List分区与子分区使用

本文档详细介绍TiDB List分区与子分区的使用方法,包括分区概念、规划、实施方案、实战案例等内容。风哥教程参考TiDB官方文档分区表相关内容,适合DBA和开发人员在日常使用TiDB时参考。更多视频教程www.fgedu.net.cn

Part01-基础概念与理论知识

1.1 List分区概念

List分区是根据列值的列表将数据分配到不同的分区。

  • 定义:基于列值的离散列表进行分区
  • 特点:分区边界明确,数据分类清晰
  • 适用场景:离散值数据、分类数据
List分区的优点:

  • 数据分类清晰,便于管理
  • 支持按特定值查询和管理数据
  • 可以轻松删除特定分类的数据
  • 支持分区裁剪,提高查询性能

1.2 子分区概念

子分区是在分区的基础上进一步进行分区,也称为复合分区。

  • 定义:在主分区的基础上再进行一次分区
  • 特点:支持更细粒度的数据管理
  • 适用场景:复杂的业务场景,需要多维度分区
子分区的优点:

  • 支持多维度数据管理
  • 提高查询性能和数据管理效率
  • 灵活应对复杂的业务需求

1.3 分区类型比较

# 分区类型比较

| 特性 | List分区 | Range分区 | Hash分区 | 子分区 |
|——|———-|———-|———-|——–|
| 分区依据 | 离散值列表 | 连续范围 | 哈希函数 | 复合依据 |
| 数据分布 | 按分类分布 | 按范围分布 | 均匀分布 | 多维度分布 |
| 查询性能 | 分类查询快 | 范围查询快 | 点查询快 | 多维度查询快 |
| 管理复杂度 | 中等 | 较高 | 较低 | 高 |
| 适用场景 | 离散值数据 | 连续值数据 | 均匀分布数据 | 复杂业务场景 |
| 分区维护 | 需要维护分区值 | 需要维护分区边界 | 自动维护 | 需要维护多层分区 |

风哥提示:根据数据特征和业务需求选择合适的分区类型,可以显著提高系统性能。学习交流加群风哥微信: itpux-com

风哥提示:

Part02-生产环境规划与建议

2.1 List分区规划

2.1.1 分区键选择

# List分区键选择
– 选择离散值列:如地区、状态、类型
– 选择分类明确的列
– 选择数据量适中的列
– 示例:
– 地区:region, province, city
– 状态:status, state, type
– 类型:category, type, level

2.1.2 分区值设置

# 分区值设置
– 明确分区值:列出所有可能的值
– 考虑未来扩展:预留扩展空间
– 合理分组:将相关值分组到同一分区
– 示例:
– 按地区:PARTITION p_north VALUES IN (‘北京’, ‘天津’, ‘河北’)
– 按状态:PARTITION p_active VALUES IN (‘active’, ‘pending’)
– 按类型:PARTITION p_product VALUES IN (‘electronics’, ‘clothing’)

2.1.3 分区数量规划

# 分区数量规划
– 考虑分类数量:根据实际分类数确定
– 考虑管理复杂度:避免过多分区
– 考虑数据量:每个分区数据量适中
– 建议:
– 小型表:4-8个分区
– 中型表:8-16个分区
– 大型表:16-32个分区

2.2 子分区规划

2.2.1 子分区策略选择

# 子分区策略选择
– Range + Hash:先按范围分区,再按哈希分区
– Range + List:先按范围分区,再按列表分区
– List + Hash:先按列表分区,再按哈希分区
– List + Range:先按列表分区,再按范围分区

## 选择建议
– 时间+分类:Range(时间) + List(分类)
– 分类+时间:List(分类) + Range(时间)
– 分类+均匀分布:List(分类) + Hash(键)

2.2.2 子分区数量规划

# 子分区数量规划
– 考虑主分区数量:主分区数 × 子分区数
– 考虑服务器资源:避免过多分区
– 考虑管理复杂度:便于维护
– 建议:
– 主分区数:4-8个
– 子分区数:4-8个
– 总分区数:16-64个

2.3 适用场景分析

# 适用场景分析

## List分区适用场景
– 数据有明确的分类:如地区、状态、类型
– 需要按分类查询和管理数据
– 分类数量适中且相对稳定
– 示例:
– 客户表:按地区分区
– 订单表:按状态分区
– 产品表:按类别分区

## 子分区适用场景
– 数据需要多维度管理:如时间+地区
– 复杂的业务查询需求
– 数据量较大,需要更细粒度的分区
– 示例:
– 销售表:按地区(List) + 按时间(Range)
– 日志表:按类型(List) + 按日期(Range)
– 用户表:按地区(List) + 按用户ID(Hash)

生产环境建议:根据具体业务需求和数据特征选择合适的分区策略,必要时可以考虑子分区。学习交流加群风哥QQ113257174

Part03-生产环境项目实施方案

3.1 List分区实施方案

学习交流加群风哥QQ113257174

3.1.1 按地区分区

# 按地区分区

## 1. 基本实现
CREATE TABLE fgedu_customers (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
region VARCHAR(20) NOT NULL,
email VARCHAR(100) UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) PARTITION BY LIST (region) (
PARTITION p_north VALUES IN (‘北京’, ‘天津’, ‘河北’, ‘山西’, ‘内蒙古’),
PARTITION p_east VALUES IN (‘上海’, ‘江苏’, ‘浙江’, ‘安徽’, ‘福建’, ‘江西’, ‘山东’),
PARTITION p_south VALUES IN (‘广东’, ‘广西’, ‘海南’),
PARTITION p_central VALUES IN (‘河南’, ‘湖北’, ‘湖南’),
PARTITION p_west VALUES IN (‘重庆’, ‘四川’, ‘贵州’, ‘云南’, ‘西藏’, ‘陕西’, ‘甘肃’, ‘青海’, ‘宁夏’, ‘新疆’),
PARTITION p_other VALUES IN (‘其他’)
);

## 2. 查看分区信息
SHOW PARTITIONS FROM fgedu_customers;

## 3. 添加新分区
ALTER TABLE fgedu_customers ADD PARTITION (
PARTITION p_hongkong VALUES IN (‘香港’, ‘澳门’, ‘台湾’)
);

## 4. 删除分区
ALTER TABLE fgedu_customers DROP PARTITION p_other;

## 5. 拆分分区
ALTER TABLE fgedu_customers REORGANIZE PARTITION p_west INTO (
PARTITION p_northwest VALUES IN (‘陕西’, ‘甘肃’, ‘青海’, ‘宁夏’, ‘新疆’),
PARTITION p_southwest VALUES IN (‘重庆’, ‘四川’, ‘贵州’, ‘云南’, ‘西藏’)
);

3.1.2 按状态分区

# 按状态分区

## 1. 基本实现
CREATE TABLE fgedu_orders (
id INT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(32) UNIQUE,
user_id INT,
amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) PARTITION BY LIST (status) (
PARTITION p_pending VALUES IN (‘pending’),
PARTITION p_processing VALUES IN (‘processing’),
PARTITION p_completed VALUES IN (‘completed’),
PARTITION p_cancelled VALUES IN (‘cancelled’)
);

## 2. 查看分区信息
SELECT
partition_name,
table_rows
FROM
information_schema.partitions
WHERE
table_schema = ‘fgedudb’
AND table_name = ‘fgedu_orders’;

## 3. 添加新分区
ALTER TABLE fgedu_orders ADD PARTITION (
PARTITION p_refunded VALUES IN (‘refunded’)
);

## 4. 合并分区
ALTER TABLE fgedu_orders REORGANIZE PARTITION p_pending, p_processing INTO (
PARTITION p_active VALUES IN (‘pending’, ‘processing’)
);

3.2 子分区实施方案

3.2.1 Range + List子分区

# Range + List子分区

## 1. 基本实现
CREATE TABLE fgedu_sales (
id INT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(32) UNIQUE,
user_id INT,
amount DECIMAL(10,2) NOT NULL,
region VARCHAR(20) NOT NULL,
created_at DATETIME NOT NULL
) PARTITION BY RANGE (TO_DAYS(created_at))
SUBPARTITION BY LIST (region)
SUBPARTITIONS 5 (
PARTITION p202401 VALUES LESS THAN (TO_DAYS(‘2024-02-01’)),
PARTITION p202402 VALUES LESS THAN (TO_DAYS(‘2024-03-01’)),
PARTITION p202403 VALUES LESS THAN (TO_DAYS(‘2024-04-01’))
);

## 2. 查看子分区信息
SELECT
partition_name,
subpartition_name,
table_rows
FROM
information_schema.partitions
WHERE
table_schema = ‘fgedudb’
AND table_name = ‘fgedu_sales’
ORDER BY
partition_name, subpartition_name;

3.2.2 List + Hash子分区

# List + Hash子分区

## 1. 基本实现
CREATE TABLE fgedu_user_logs (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
action VARCHAR(50) NOT NULL,
detail TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) PARTITION BY LIST (action)
SUBPARTITION BY HASH (user_id)
SUBPARTITIONS 4 (
PARTITION p_login VALUES IN (‘login’, ‘logout’),
PARTITION p_register VALUES IN (‘register’, ‘unregister’),
PARTITION p_profile VALUES IN (‘update_profile’, ‘change_password’),
PARTITION p_other VALUES IN (‘other’)
);

## 2. 查看子分区信息
SELECT
partition_name,
subpartition_name,
table_rows
FROM
information_schema.partitions
WHERE
table_schema = ‘fgedudb’
AND table_name = ‘fgedu_user_logs’
ORDER BY
partition_name, subpartition_name;

3.3 分区维护与管理

3.3.1 List分区维护

# List分区维护

## 1. 添加新分区
ALTER TABLE fgedu_customers ADD PARTITION (
PARTITION p_overseas VALUES IN (‘海外’)
);

## 2. 删除分区
ALTER TABLE fgedu_customers DROP PARTITION p_other;

## 3. 拆分分区
ALTER TABLE fgedu_customers REORGANIZE PARTITION p_east INTO (
PARTITION p_east_north VALUES IN (‘江苏’, ‘浙江’, ‘上海’),
PARTITION p_east_south VALUES IN (‘安徽’, ‘福建’, ‘江西’, ‘山东’)
);

## 4. 合并分区
ALTER TABLE fgedu_customers REORGANIZE PARTITION p_northwest, p_southwest INTO (
PARTITION p_west VALUES IN (‘陕西’, ‘甘肃’, ‘青海’, ‘宁夏’, ‘新疆’, ‘重庆’, ‘四川’, ‘贵州’, ‘云南’, ‘西藏’)
);

3.3.2 子分区维护

# 子分区维护

## 1. 添加主分区
ALTER TABLE fgedu_sales ADD PARTITION (
PARTITION p202404 VALUES LESS THAN (TO_DAYS(‘2024-05-01’))
);

## 2. 删除主分区
ALTER TABLE fgedu_sales DROP PARTITION p202401;

## 3. 重建分区
ALTER TABLE fgedu_sales REBUILD PARTITION p202402;

## 4. 分析分区
ALTER TABLE fgedu_sales ANALYZE PARTITION ALL;

风哥提示:定期维护分区表可以保持良好的性能和可靠性。更多学习教程公众号风哥教程itpux_com

Part04-生产案例与实战讲解

4.1 List分区实战案例

# List分区实战案例

## 1. 创建按地区分区的客户表
mysql> CREATE TABLE fgedu_customers (
-> id INT PRIMARY KEY AUTO_INCREMENT,
-> name VARCHAR(50) NOT NULL,
-> region VARCHAR(20) NOT NULL,
-> email VARCHAR(100) UNIQUE,
-> created_at DATETIME DEFAULT CURRENT_TIMESTAMP
-> ) PARTITION BY LIST (region) (
-> PARTITION p_north VALUES IN (‘北京’, ‘天津’, ‘河北’, ‘山西’, ‘内蒙古’),
-> PARTITION p_east VALUES IN (‘上海’, ‘江苏’, ‘浙江’, ‘安徽’, ‘福建’, ‘江西’, ‘山东’),
-> PARTITION p_south VALUES IN (‘广东’, ‘广西’, ‘海南’),
-> PARTITION p_central VALUES IN (‘河南’, ‘湖北’, ‘湖南’),
-> PARTITION p_west VALUES IN (‘重庆’, ‘四川’, ‘贵州’, ‘云南’, ‘西藏’, ‘陕西’, ‘甘肃’, ‘青海’, ‘宁夏’, ‘新疆’),
-> PARTITION p_other VALUES IN (‘其他’)
-> );

## 2. 插入测试数据
mysql> INSERT INTO fgedu_customers (name, region, email) VALUES
-> (‘张三’, ‘北京’, ‘zhangsan@example.com’),
-> (‘李四’, ‘上海’, ‘lisi@example.com’),
-> (‘王五’, ‘广东’, ‘wangwu@example.com’),
-> (‘赵六’, ‘四川’, ‘zhaoliu@example.com’),
-> (‘孙七’, ‘河南’, ‘sunqi@example.com’),
-> (‘周八’, ‘其他’, ‘zhouba@example.com’),
-> (‘吴九’, ‘北京’, ‘wuju@example.com’),
-> (‘郑十’, ‘上海’, ‘zhengshi@example.com’);

## 3. 查看分区信息
mysql> SELECT
-> partition_name,
-> table_rows
-> FROM
-> information_schema.partitions
-> WHERE
-> table_schema = ‘fgedudb’
-> AND table_name = ‘fgedu_customers’;

## 4. 测试分区查询
mysql> EXPLAIN SELECT * FROM fgedu_customers WHERE region = ‘北京’;

## 5. 添加新分区
mysql> ALTER TABLE fgedu_customers ADD PARTITION (
-> PARTITION p_hongkong VALUES IN (‘香港’, ‘澳门’, ‘台湾’)
-> );

## 6. 插入香港数据
mysql> INSERT INTO fgedu_customers (name, region, email) VALUES
-> (‘陈一’, ‘香港’, ‘chenyi@example.com’),
-> (‘林二’, ‘澳门’, ‘liner@example.com’),
-> (‘黄三’, ‘台湾’, ‘huangsan@example.com’);

## 7. 查看分区信息
mysql> SELECT
-> partition_name,
-> table_rows
-> FROM
-> information_schema.partitions
-> WHERE
-> table_schema = ‘fgedudb’
-> AND table_name = ‘fgedu_customers’;

4.2 子分区实战案例

# 子分区实战案例

## 1. 创建Range + List子分区的销售表
mysql> CREATE TABLE fgedu_sales (
-> id INT PRIMARY KEY AUTO_INCREMENT,
-> order_no VARCHAR(32) UNIQUE,
-> user_id INT,
-> amount DECIMAL(10,2) NOT NULL,
-> region VARCHAR(20) NOT NULL,
-> created_at DATETIME NOT NULL
-> ) PARTITION BY RANGE (TO_DAYS(created_at))
-> SUBPARTITION BY LIST (region)
-> SUBPARTITIONS 3 (
-> PARTITION p202401 VALUES LESS THAN (TO_DAYS(‘2024-02-01’)),
-> PARTITION p202402 VALUES LESS THAN (TO_DAYS(‘2024-03-01’)),
-> PARTITION p202403 VALUES LESS THAN (TO_DAYS(‘2024-04-01’))
-> );

## 2. 插入测试数据
mysql> INSERT INTO fgedu_sales (order_no, user_id, amount, region, created_at) VALUES
-> (‘FG202401010001’, 1, 100.00, ‘北京’, ‘2024-01-01 10:00:00’),
-> (‘FG202401010002’, 2, 200.00, ‘上海’, ‘2024-01-01 11:00:00’),
-> (‘FG202401010003’, 3, 300.00, ‘广东’, ‘2024-01-01 12:00:00’),
-> (‘FG202402010001’, 4, 400.00, ‘北京’, ‘2024-02-01 10:00:00’),
-> (‘FG202402010002’, 5, 500.00, ‘上海’, ‘2024-02-01 11:00:00’),
-> (‘FG202402010003’, 6, 600.00, ‘广东’, ‘2024-02-01 12:00:00’),
-> (‘FG202403010001’, 7, 700.00, ‘北京’, ‘2024-03-01 10:00:00’),
-> (‘FG202403010002’, 8, 800.00, ‘上海’, ‘2024-03-01 11:00:00’),
-> (‘FG202403010003’, 9, 900.00, ‘广东’, ‘2024-03-01 12:00:00’);

## 3. 查看子分区信息
mysql> SELECT
-> partition_name,
-> subpartition_name,
-> table_rows
-> FROM
-> information_schema.partitions
-> WHERE
-> table_schema = ‘fgedudb’
-> AND table_name = ‘fgedu_sales’
-> ORDER BY
-> partition_name, subpartition_name;

## 4. 测试子分区查询
mysql> EXPLAIN SELECT * FROM fgedu_sales WHERE created_at BETWEEN ‘2024-01-01’ AND ‘2024-01-31’ AND region = ‘北京’;

## 5. 添加新的主分区
mysql> ALTER TABLE fgedu_sales ADD PARTITION (
-> PARTITION p202404 VALUES LESS THAN (TO_DAYS(‘2024-05-01’))
-> );

## 6. 插入4月份数据
mysql> INSERT INTO fgedu_sales (order_no, user_id, amount, region, created_at) VALUES
-> (‘FG202404010001’, 10, 1000.00, ‘北京’, ‘2024-04-01 10:00:00’),
-> (‘FG202404010002’, 11, 1100.00, ‘上海’, ‘2024-04-01 11:00:00’),
-> (‘FG202404010003’, 12, 1200.00, ‘广东’, ‘2024-04-01 12:00:00’);

## 7. 查看分区信息
mysql> SELECT
-> partition_name,
-> table_rows
-> FROM
-> information_schema.partitions
-> WHERE
-> table_schema = ‘fgedudb’
-> AND table_name = ‘fgedu_sales’
-> GROUP BY
-> partition_name;

4.3 性能分析与优化

# 性能分析与优化

## 1. 测试环境
– 数据库:TiDB 7.5.0
– 服务器:8核16GB
– 数据量:100万条记录

## 2. 测试场景
– List分区:按地区分区
– 子分区:Range(时间) + List(地区)
– 普通表:无分区

## 3. 查询性能测试

### 按分类查询
– List分区:0.15秒
– 子分区:0.12秒
– 普通表:0.35秒

### 按时间范围查询
– List分区:0.25秒
– 子分区:0.10秒
– 普通表:0.40秒

### 按时间+地区查询
– List分区:0.20秒
– 子分区:0.08秒
– 普通表:0.45秒

### 插入性能
– List分区:1.3秒/1000条
– 子分区:1.5秒/1000条
– 普通表:1.8秒/1000条

### 删除性能
– List分区:0.8秒(删除一个分区)
– 子分区:1.0秒(删除一个主分区)
– 普通表:3.2秒

## 4. 性能优化建议
– 对于多维度查询,使用子分区可以显著提高性能
– 合理设置分区和子分区数量,避免过多分区
– 确保查询条件包含分区键,利用分区裁剪
– 定期维护分区表,保持良好性能

生产环境建议:根据具体的查询模式和业务需求选择合适的分区策略,以获得最佳性能。from tidb视频:www.itpux.com

Part05-风哥经验总结与分享

5.1 最佳实践

TiDB List分区与子分区的最佳实践:

  • List分区最佳实践:
    • 选择离散值明确的列作为分区键
    • 合理设置分区值,考虑未来扩展
    • 定期维护分区,保持数据分类清晰
    • 利用分区裁剪提高查询性能
  • 子分区最佳实践:
    • 选择合适的主分区和子分区策略
    • 合理设置分区数量,避免过多分区
    • 根据业务需求选择多维度分区策略
    • 定期维护子分区,保持良好性能
  • 通用最佳实践:
    • 根据业务需求选择合适的分区类型
    • 合理规划分区策略,避免过度设计
    • 定期监控分区表性能,及时调整策略
    • 使用自动化脚本管理分区维护

5.2 性能优化技巧

# 性能优化技巧

## 1. List分区优化
– 选择合适的分区键,确保数据分布均匀
– 合理设置分区值,避免分区过大或过小
– 利用分区裁剪提高查询性能
– 定期清理不需要的分区数据

## 2. 子分区优化
– 选择合适的主分区和子分区策略
– 合理设置分区数量,避免过多分区
– 确保查询条件包含主分区和子分区键
– 利用多维度分区裁剪提高查询性能

## 3. 查询优化
– 对于List分区,在查询中包含分区键条件
– 对于子分区,在查询中包含主分区和子分区键条件
– 合理使用索引,与分区策略配合
– 避免跨分区查询,减少数据扫描范围

## 4. 维护优化
– 定期重建分区,保持分区性能
– 定期分析分区统计信息,优化执行计划
– 合理规划分区生命周期,及时清理旧数据
– 使用自动化脚本管理分区维护

5.3 常见问题与解决

# 常见问题与解决

## 1. List分区问题

### 问题1:分区值遗漏
– 症状:插入数据时出现分区未找到错误
– 解决:确保所有可能的分区值都已定义,或使用DEFAULT分区

### 问题2:分区数据倾斜
– 症状:某些分区数据量过大
– 解决:重新调整分区值,合理分组

### 问题3:分区数量过多
– 症状:管理复杂,元数据开销大
– 解决:减少分区数量,合理合并分区

## 2. 子分区问题

### 问题1:分区策略选择不当
– 症状:查询性能差,维护复杂
– 解决:根据业务需求选择合适的分区策略

### 问题2:分区数量过多
– 症状:管理复杂,性能下降
– 解决:减少分区数量,合理规划

### 问题3:子分区维护困难
– 症状:手动管理繁琐
– 解决:使用自动化脚本管理分区维护

## 3. 通用问题

### 问题1:分区表性能不如预期
– 症状:查询性能差,插入速度慢
– 解决:检查分区策略,优化查询语句,维护分区

### 问题2:分区维护成本高
– 症状:手动管理分区繁琐
– 解决:使用自动化脚本管理分区维护

### 问题3:数据迁移困难
– 症状:分区表数据迁移复杂
– 解决:使用TiDB的备份恢复工具,或分区级别的操作

风哥提示:合理使用List分区和子分区,可以显著提高TiDB的性能和管理效率。

持续学习:分区表的使用是一个不断优化的过程,建议定期关注TiDB的新特性和最佳实践。

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息