当前位置: 首页 > news >正文

MySQL 数据操纵与数据库优化

MySQL数据库的DML

一、创建(Create)

1. 基本语法

INSERT INTO 表名 [(列名1, 列名2, ...)] 
VALUES (值1, 值2, ...);
  • 省略列名条件:当值的顺序与表结构完全一致时,可省略列名(需包含所有字段值)
  • 批量插入:单条语句插入多行数据提升效率
    INSERT INTO student (id, name, score) VALUES
    (1, '张三', 99), (2, '李四', 88), (3, '王五', 77);

2. 高级技巧

  • 自增主键处理:使用AUTO_INCREMENT时,无需显式插入主键值
  • 大数据量优化:调整max_allowed_packet参数避免数据包过大错误
    SET GLOBAL max_allowed_packet = 1024*1024*100; -- 扩容至100MB[1][8]
  • 核心功能max_allowed_packet 定义了 MySQL 服务器和客户端之间传输的数据包最大允许大小。当执行大容量插入、更新或查询时,若数据包超过该限制,会触发 PacketTooBigException 错误。
  • 适用场景:处理大型 BLOB 字段、批量导入数据、数据迁移等需要传输大容量数据的操作。
  • 临时生效:通过 SET GLOBAL 修改的参数仅在当前 MySQL 服务运行期间生效,重启服务后会恢复为配置文件中的默认值。若需永久生效,需修改配置文件(如 my.cnf 或 my.ini)并重启服务。
  • 单位限制
    • 在命令行中设置时,只能使用字节数(如 1024*1024*100),不可直接使用 M 或 G 单位。
    • 在配置文件中则支持 M/G 单位(如 max_allowed_packet=100M)。
  • 取值范围:最小值为 1KB,最大值为 1GB(超过会自动调整为 1GB)。

二、读取(Retrieve)

1. 基础查询

  • 全列查询SELECT * FROM 表名(需警惕性能问题,建议指定必要字段)
  • 别名设置:增强结果可读性
    SELECT name AS 学生姓名, age+5 AS 修正年龄 FROM student;

2. 聚合函数与分组

  • 核心聚合函数
    SELECT COUNT(*) AS 总人数, AVG(score) AS 平均分,MAX(score) AS 最高分 
    FROM exam_result;
    • COUNT统计行数时推荐使用COUNT(*),避免NULL值干扰
  • 分组查询
    SELECT course_id, AVG(grade) 
    FROM study 
    GROUP BY course_id 
    HAVING AVG(grade) > 80; -- HAVING对分组后数据筛选[4][5]
    与WHERE区别:WHERE在分组前过滤,HAVING在分组后过滤

3. 子查询

  • WHERE子句嵌套
    SELECT name 
    FROM student 
    WHERE id IN (SELECT student_id FROM study WHERE course_id = 'CS101'
    );
  • FROM子句派生表
    SELECT t.dept_name, avg_salary 
    FROM (SELECT dept_id, AVG(salary) AS avg_salary FROM emp GROUP BY dept_id
    ) t;

4. 多表连接

  • 内连接:仅返回匹配记录
    SELECT s.name, sc.score 
    FROM student s 
    INNER JOIN study sc ON s.id = sc.student_id;
  • 左外连接:保留左表所有记录
    SELECT s.name, sc.score 
    FROM student s 
    LEFT JOIN study sc ON s.id = sc.student_id;

三、更新(Update)

1. 基础语法

UPDATE 表名 
SET 列名1=值1, 列名2=值2 
WHERE 条件; -- 必须指定条件避免全表更新[8][9]

示例UPDATE emp SET salary=salary*1.1 WHERE dept='研发部';

2. 级联更新

UPDATE study 
SET grade=grade+5 
WHERE course_id IN (SELECT id FROM course WHERE teacher='张教授'
);

四、删除(Delete)

1. 条件删除

DELETE FROM 表名 WHERE 条件; -- 未加条件将清空全表[8]

示例DELETE FROM log WHERE create_time < '2023-01-01';

2. 高效清空(巧用DDL)

TRUNCATE TABLE student; -- 重置自增主键,性能优于DELETE[1][8]

限制:外键约束存在时不可用,需先解除约束

五、约束与完整性

1. 主键与外键

CREATE TABLE student_course (student_id INT REFERENCES student(id) ON DELETE CASCADE,course_id INT REFERENCES course(id),PRIMARY KEY(student_id, course_id) -- 复合主键[1][5]
);
  • 级联操作ON DELETE CASCADE实现主表删除时自动清理关联数据

2. 唯一性与默认值

CREATE TABLE user (id INT AUTO_INCREMENT PRIMARY KEY,email VARCHAR(255) UNIQUE, -- 唯一约束status TINYINT DEFAULT 1 -- 默认值约束[8][9]
);

小结

MySQL CRUD操作是数据库开发的基础,掌握其正确使用规则可以提高开发效率和数据安全性。在实际应用中,需要注意以下几点:

  1. 避免频繁使用SELECT *,尽量指定需要的列。
  2. 更新和删除操作时,务必添加WHERE条件,防止误操作。
  3. 使用TRUNCATE时,确保表中没有外键约束。
  4. 合理设计表结构和约束,提高数据的完整性和一致性。

MySQL数据库优化

一、查询优化:从 SQL 到索引的全面调优

  1. EXPLAIN 分析查询(查执行计划)

    EXPLAIN SELECT * FROM users WHERE email = 'user@example.com';
    • 关键字段解读
      • typeALL(全表扫描,需优化)→ 目标优化到 ref 或 range
      • key:显示实际使用的索引,若为 NULL 表示未用索引
      • rows:预估扫描行数,数值越大性能越差
      • Extra:出现 Using filesort(额外排序)或 Using temporary(临时表)需警惕
  2. 避免全表扫描的 3 大技巧

    • 索引覆盖:确保 WHERE、JOIN、ORDER BY 涉及的列都有索引
    • 函数陷阱:禁止在索引列用函数(如 YEAR(created_at)),改用范围查询
      -- 错误:索引失效
      SELECT * FROM users WHERE YEAR(created_at) = 2023;
      -- 正确:索引生效
      SELECT * FROM users WHERE created_at BETWEEN '2023-01-01' AND '2023-12-31';
    • 模糊查询优化:避免 LIKE '%abc%',改用 LIKE 'abc%'(前缀匹配可用索引)
  3. 索引优化的黄金法则

    • 覆盖索引:查询字段全在索引中,无需回表
      CREATE INDEX idx_email_name ON users(email, name);  -- 联合索引
      SELECT email, name FROM users WHERE email = 'user@example.com';  -- 直接命中索引
    • 前缀索引:对长文本(如地址)截取前 20 字符建索引,节省空间 
      CREATE INDEX idx_title_prefix ON articles(title(20));
    • 索引避坑
      • 删除未使用的索引(如单字段索引被联合索引覆盖)
      • 联合索引顺序遵循最左前缀原则(a,b,c) 索引对 aa,b 生效,对 b,c 无效)
  4. JOIN 与分页的高效写法

    • JOIN 优化
      • 用小表驱动大表(如 FROM 小表 JOIN 大表
      • 确保关联字段有索引,避免笛卡尔积
    • 分页优化(百万级数据场景):
      -- 传统分页(慢):需扫描前 100000 行
      SELECT * FROM users LIMIT 100000, 10;
      -- 优化方案:通过覆盖索引跳过偏移量
      SELECT * FROM users 
      WHERE id >= (SELECT id FROM users ORDER BY id LIMIT 100000, 1)
      ORDER BY id LIMIT 10;

二、表结构优化:从设计到存储的进阶

  1. 数据类型选择

    • 数值型优先:用 INT 存 IP(INET_ATON() 转换),而非 VARCHAR
    • 避免 NULL:用默认值(如空字符串)替代,减少索引复杂度
    • ENUM 妙用:有限值字段(如性别)用 ENUM 比 VARCHAR 更省空间
  2. 范式与反范式的平衡

    • 范式化(减少冗余):适合写多读少场景(如日志表)
    • 反范式化(适当冗余):读多写少场景(如用户表冗余常用字段)
  3. 分区与分库分表

    • 分区表:按时间切分历史数据,加速查询
      CREATE TABLE logs (id INT, log_date DATE)
      PARTITION BY RANGE (YEAR(log_date)) (PARTITION p2020 VALUES LESS THAN (2021),PARTITION p2023 VALUES LESS THAN (2024)
      );
    • 分库分表:单表超千万行时用 ShardingSphere 分片

三、服务器参数调优:关键配置详解

  1. InnoDB 核心参数

    innodb_buffer_pool_size = 16G  # 物理内存的 70%-80%
    innodb_file_per_table = ON  # 每个表独立表空间
  2. 查询缓存慎用

    • 适用场景:读多写极少(如静态配置表)
    • 禁用场景:高并发写入时,缓存频繁失效反降低性能
      query_cache_type = 0  # 高写入场景关闭
  3. 连接与内存管理

    max_connections = 500  # 根据业务负载调整
    wait_timeout = 600  # 空闲连接 10 分钟断开
    tmp_table_size = 64M  # 增大临时表内存

四、架构优化:高可用与扩展方案

  1. 读写分离
    • 主库处理写操作,从库处理读请求(用 ProxySQL 路由)
  2. 高可用方案
    • MHA:自动故障转移,主库宕机 30 秒内切换
    • Galera Cluster:多主同步,适合写负载均衡场景
  3. 缓存与负载均衡
    • Redis 缓存热点数据:减少数据库压力
    • HAProxy:均衡读请求到多个从库

五、锁与事务优化:并发控制秘诀

  1. 隔离级别选择

    • 默认 REPEATABLE READ 适合多数场景
    • 高并发读写可用 READ COMMITTED 减少锁竞争
  2. 死锁监控与处理

    innodb_print_all_deadlocks = 1  # 记录死锁日志
    • 重试机制:代码层捕获死锁异常后自动重试

六、监控与工具:数据库的“健康管家”

  1. 内置工具

    • 慢查询日志:定位耗时 SQL 
      slow_query_log = 1
      long_query_time = 2  # 记录超过 2 秒的查询
    • SHOW PROCESSLIST:实时查看活跃连接
  2. 第三方利器

    • Percona Toolkit:分析索引效率与表结构
    • Prometheus + Grafana:可视化监控 QPS、连接数等

七、硬件与系统优化:底层性能基石

  1. 磁盘与文件系统

    • SSD 替代 HDD:随机读写性能提升 10 倍+
    • XFS 文件系统:禁用 atime 减少磁盘写入
      mount -o noatime,nodiratime /dev/sdb1 /data
  2. 内核参数调优

    • TCP 缓冲区:增大网络吞吐量
    • 文件句柄数:避免 Too many open files 错误

八、持续维护:数据库的“养生之道”

  1. 定期维护
    • 每月优化碎片化表:OPTIMIZE TABLE large_table;
    • 清理历史数据:分区表直接 DROP PARTITION
  2. 避免过度优化
    • 二八原则:优先优化 20% 高频查询
    • 业务优先:架构扩展前评估投资回报率(如分库分表成本高)

优化顺序指南

  1. 紧急处理:慢查询优化(见效最快)
  2. 结构调优:索引、表设计、分区
  3. 参数调优:InnoDB 配置、连接数
  4. 架构扩展:读写分离、缓存层
  5. 硬件升级:SSD、内存扩容

总结

MySQL 优化是持续过程,需结合业务场景选择策略。建议从 EXPLAIN 分析和索引优化入手,逐步深入架构设计。记住:“没有银弹,只有最适合的方案!”

    相关文章:

  1. PostGreSQL:数据表被锁无法操作
  2. Spark 中RDD、Job,stage,task的关系
  3. c++STL-string的使用
  4. 接口的基础定义与属性约束
  5. Nginx 使用 Keepalived 搭建 nginx 高可用
  6. (十二)Java枚举类深度解析:从基础到高级应用
  7. 数据分析预备篇---NumPy数组
  8. ARP协议的工作原理
  9. JavaScript学习教程,从入门到精通,jQuery Mobile 移动页面开发语法知识点及案例代码(42)
  10. 【Beat Saber 节奏光剑】全身动捕直播搭建指南
  11. 销售管理系统使用全攻略:从基础配置到数据分析
  12. 《Go小技巧易错点100例》第三十二篇
  13. 实战项目1(02)
  14. 《AI大模型应知应会100篇》第55篇:大模型本地开发环境搭建
  15. NB-IoT嵌入式产品开发有哪些坑?
  16. TIME - MoE 模型代码 5——Time-MoE-main/time_moe/utils/log_util.py
  17. Scrapy 核心组件解析:Request Response 的深度应用与实战
  18. Web 性能优化四:资源体积压缩与加载策略详解:JS / CSS / 图片 / 字体怎么减负?
  19. 风扇接口
  20. 0基础 | L298N电机驱动模块 | 使用指南
  21. 三亚通报救护车省外拉警报器开道旅游:违规违法,责令公司停业整顿
  22. 外企聊营商|波音速度:创新审批促“起飞”
  23. 工人日报:“鼠标手”被纳入职业病,劳动保障网越织越密
  24. 青海规范旅游包车行为:不得引导外省籍旅游包车违规驻地运营
  25. 全球医药股普跌,A股创新药板块下挫
  26. “海豚音”依旧互动更多,玛丽亚·凯莉本周来沪开唱