sql优化进阶

一、基本概念:

1、分区:是将一个大表按照物理维度分割成多个更小、更易管理的部分过程;

2、举例:你有一个包含了数年销售记录的大表sales表,随着时间推移,表的数据量会非常的大,查询和维护成本会非常高,分区相当于给这个表安装了多个抽屉;

  • 逻辑上 :你仍然只有一个sales表,你可以像以前一样SELECT * FROM sales ...

  • 物理上:数据库将数据存储在不同的物理分区中。例如,2023年的数据在一个分区(一个抽屉),2024年的数据在另一个分区。

这样做的好处当你查询2024年某个分区的数据时,数据库可以智能的扫描2024分区的数据,无需对整个表进行扫描,极大的增加了查询性能。

二、分区的主要类型:

2.1、范围分区:

按照某个列的值的范围进行数据划分,一般按照时间和数值进行分区

  • 示例 :按sale_date字段分区。

    • 分区 p2023sale_date < '2024-01-01'

    • 分区 p2024sale_date >= '2024-01-01' AND sale_date < '2025-01-01'

    • 分区 p2025sale_date >= '2025-01-01'

2.2、列表分区:

按照某个列具体的值来划分数据,适用于离散和可枚举的值,如地区、状态

  • 示例 :按region字段分区。

    • 分区 p_eastregion IN ('Shanghai', 'Jiangsu', 'Zhejiang')

    • 分区 p_westregion IN ('Sichuan', 'Chongqing')

    • 分区 p_northregion IN ('Beijing', 'Tianjin')

2.3、HASH分区:

根据数据库对分区键的哈希值来随机分配数据。目的是将数据均匀分布到指定数量的分区中。

  • 示例 :按user_id字段哈希分区。

    • 你指定分成4个分区,数据库会自动计算HASH(user_id) % 4,将数据均匀分配到4个分区中。

2.4、复合分区:

结合上述两种或多种分区策略。例如,先按范围分区,再在每个范围内按列表或哈希分区。

三、实际落地操作:

3.1、范围分区:

sql 复制代码
-- 1. 创建分区表
CREATE TABLE sales (
    sale_id INT NOT NULL,
    product_id INT,
    sale_date DATE,
    amount DECIMAL(10, 2)
)
PARTITION BY RANGE (YEAR(sale_date)) ( -- 使用YEAR函数提取年份作为分区键
    PARTITION p2020 VALUES LESS THAN (2021),
    PARTITION p2021 VALUES LESS THAN (2022),
    PARTITION p2022 VALUES LESS THAN (2023),
    PARTITION p2023 VALUES LESS THAN (2024),
    PARTITION p_future VALUES LESS THAN MAXVALUE -- 用于存储超出定义范围的数据
);

执行计划分析:

使用 SELECT * FROM sales PARTITION (p2023) 或者 SELECT * FROM sales WHERE sale_date = '2023-10-20'

EXPLAIN SELECT * FROM sales WHERE sale_date = '2023-10-20';

在执行计划中只扫描了`partitions: p2023`,表示它只扫描了p2023分区

3.2、管理分区:

sql 复制代码
-- 添加新分区(例如为2024年)
ALTER TABLE sales ADD PARTITION (
    PARTITION p2024 VALUES LESS THAN (2025)
);

-- 删除旧分区(这会删除整个分区的数据!请谨慎操作)
ALTER TABLE sales DROP PARTITION p2020;

四、分区的优缺点

优点:
  1. 性能提升 :通过分区裁剪,查询只扫描相关分区,极大减少I/O。

  2. 维护性增强

    • 可以快速删除 整个分区(如删除过期的历史数据),比DELETE操作快得多。

    • 可以对单个分区进行备份、恢复、重建索引等操作,不影响其他分区。

缺点和注意事项:
  1. 设计复杂性:分区键的选择至关重要,选错了可能无法带来性能提升。

  2. 分区键选择:通常只能基于一个或几个列。一旦选定,修改困难。

  3. 潜在性能问题

    • 如果查询条件不包含分区键,可能会导致扫描所有分区,性能可能更差。

    • 主键或唯一键必须包含分区键字段。

  4. 分区数量:分区不是越多越好,过多的分区会带来元数据管理的开销。

相关推荐
Adorable老犀牛3 小时前
Linux-db2look创建表结构详细参数
linux·数据库·db2
disanleya3 小时前
MySQL时间格式转换,时间数据混乱不堪如何彻底重构?
数据库·mysql·重构
奥尔特星云大使3 小时前
mysql读写分离中间件——Atlas详解
数据库·mysql·中间件·dba·读写分离
默|笙4 小时前
【c++】set和map的封装
android·数据库·c++
一水鉴天4 小时前
整体设计 逻辑系统程序 之20 程序设计 含分层架构、CNN 数据处理支撑、监督闭环与多场景交付物 之1 cnn_project
数据库·人工智能·算法
zym大哥大4 小时前
Redis-List
数据库·redis·缓存
正在走向自律5 小时前
国产之光金仓数据库,真能平替MongoDB?实测来了!
数据库
RestCloud5 小时前
PostgreSQL的数据集成之路:ETL+CDC实现实时多源聚合
数据库·数据仓库·postgresql·etl·数据处理·数据传输·数据同步