• MySQL 基础知识点小结

MySQL 基础知识点小结

2025-05-19 10:00:08 栏目:宝塔面板 34 阅读

本文针对MySQL一些常见比较重要的知识点进行了详细的总结,希望对你有帮助。

MySQL如何执行一条SQL

参考笔者这篇文章进行了详细的总结:《深入剖析 MySQL 某条执行过程

MySQL支持的存储引擎有哪些

通过下面show engines;这段命令即查看MySQL默认的存储引擎。对应的查询结果如下图所示,可以看到MySQL默认采用InnoDB作为存储引擎。而且InnoDB是MySQL中唯一一个支持事务性存储的存储引擎。

同时MySQL早期用的存储引擎就是MyISAM ,然后变成InnoDB,因为MySQL采用的是插件时存储引擎,所以存储引擎是可以任意切换的,

注意:存储引擎配置所针对的维度是针对表的,而不是针对某张数据库的,如下建表语句,我们就将存储引擎设置为innodb :

-- 测试脚本
drop table if exists `test`;
create table `test` (
    `id` bigint not null comment 'id',
    `name` varchar(50) comment '名称',
    `password` varchar(50) comment '密码',
    primary key (`id`)
) engine=innodb default charset=utf8mb4 comment '测试';

MyISAM和InnoDB的区别

MyISAM的特点:

  • 它在性能方面表现出色,例如全文索引、压缩、空间函数等都没问题。
  • 只支持表级锁。
  • 不支持事务。
  • 不支持故障后安全恢复。
  • 因为不支持行级锁,所以就不支持MVCC。
  • MyISAM存储引擎数据和索引文件是分开。
  • 不支持外键。

InnoDB的特点:

  • 支持行级锁。
  • 因为行级锁,所以支持MVCC,通过MVCC保证了repeat read(可重复读)的效率,并通过间隙锁防止幻行插入所导致的幻读的问题。
  • 支持事务,所以并发读写的情况下性能优异。
  • 同时支持故障后安全恢复(依赖redolog),
  • 也支持外键,但是一般情况下我们不太建议开发数据表使用外键。

特定情况下的索引和数据都在同一个文件上,也就是我们常说的聚簇索引,通过聚簇索引可以保证高效快速的主键查询,因为二级索引包含主键列,所以但如果主键占用物理空间过大的话,二级索引占用的空间也会很大,所以如果存在多个索引的情况下,建议适当调小主键索引的大小。

什么是多版本并发控制(MVCC)

可以参考笔者这篇关于mvcc的讲解,解释的比较全面:《详解 undoLog 在 MySQL 多版本并发控制 MVCC 中的运用》

如何选择MyISAM和InnoDB

大部分情况下都建议使用InnoDB,很多人认为MyISAM性能要好于InnoDB,事实并非如此,在《高性能MySQL》中提及过:

不要轻易相信“MyISAM 比 InnoDB 快”之类的经验之谈,这个结论往往不是绝对的。在很多我们已知场景中,InnoDB 的速度都可以让 MyISAM 望尘莫及,尤其是用到了聚簇索引,或者需要访问的数据都可以放入内存的应用。

现代应用软件系统大部分都是用于处理一些短期的事务,且大部分情况下是不需要回滚的,所以InnoDB是个不错的选择,况且InnoDB是可以通过redo.log完成数据崩溃后恢复,这一点是MyISAM所不具备的,这也就是为了MySQL8.0之后将InnoDB作为默认的存储引擎。

MySQL字段char和varchar 的区别

我们先来说说varchar,varchar 常用于存储一些不定长的字段数据,它会通过1-2字节来记录字段长度,后续字节用于记录可变长字符串:

因为是可变长的缘故,所以在于字符串区间变化较大的场景下,相对于char它会更加节省存储空间,同样的缺点也很明显,如果涉及大量修改varchar字段导致原有空间无法容纳varchar时,就可能导致页分裂来容纳行。

所以varchar可能更适合字段长度不一定大量趋近于平均长度,且更新较少长度变化不大(不容易产生碎片)的场景。

而char则时定长的空间,如果字符长度不足则用结束符标记字符串结束,对于字符串较短或者长度几乎相同、修改较少的场景,使用char性能表现会比前者更出色一些,因为char长度固定,碎片较少,可以很少的利用局部性原理IO大量数据。

需要了解的是varchar(30) 代表存30个字符,其中中文占3字节,所以30个字符要占用90字节。英文是1字节。

我们可以键入下面sql,这里补充一下char_length获取的字符长度,有几个字符长度就是多少,length算的是字节数,查看可以看到length('哈哈')为6,length('hh')为2。

select char_length('哈哈'),length('哈哈');

中文字符串长度的输出结果:

char_length('哈哈')|length('哈哈')|
-----------------+------------+
                2|           6|

英文字符长度查询SQL:

select char_length('hh'),length('hh');

英文字符长度输出结果:

char_length('hh')|length('hh')|
-----------------+------------+
                2|           2|

如何开启MySQL看查询缓存

通过修改my.cnf中加入下面这段配置即可:

query_cache_type=1
query_cache_size=600000

查询缓存不命中的几个特殊场景是什么

  • 查询SQL一样,但是字符串大小写不一样。
  • 查询的SQL涉及自定义函数、用户变量、临时表、MySQL库中的表等情况,MySQL服务器不会缓存数据。
  • 一旦我们进行数据更新或者表结构调整的情况,那么缓存也会被清理掉。
  • 缓存空间满了,会根据缓存回收算法去清空SQL缓存。

MySQL磁盘爆满对应的解决方案

我们需要根据不同的原因进行相应的处理:

  • 数据量暴增:这就得多方面考虑了,为什么会暴增,暴增是否因为业务涉及不合理,我们是否可以从功能上进行优化,例如某些日志分表存储着一些过期的稽核数据,我们是否可以适当的将这些表空间数据释放,若实在无法进行空间释放,可以考虑服务进行磁盘扩容了。
  • 日志:日志导致容量暴增基本就bin log或者error日志没有及时清理了,这种情况我们只能删除一些binlog即可了。
  • 临时文件:数据库某些查询结果都会放在内存的,当内存空间不足时就会为查询结果生成一个临时文件(例如对并发场景下各种大表进行select * from table),就很可能产生大量临时文件,进而出现CPU爆满和IO次数激增。

针对临时文件爆满问题,对应的解决方式也很简单,首先找到临时文件的位置:

show variables like 'tmpdir'

然后到达对应的位置将临时文件内容置空:

echo '' >> host-xxxxx.log

注意:我们此时可能还需清除慢查询SQL,查看是否有time数据很大的慢查询

SELECT id, `state`, user,host,time,`INFO` FROM information_schema.processlist where state IS NOT NULL  and state <> "" ORDER BY time desc;

如果有则杀掉:

SELECT concat('kill ', id, ';') FROM information_schema.processlist where user = 'HispaceCMS' and  `COMMAND` = 'Query' and  state IS NOT NULL and state <> '' and DB is not null and time > 1000 ORDER BY time desc

MySQL中的count(*)、count(1)、count(列名)的区别

回答这个问题我们不妨做个实验,首先建立数据表:

create table count_test(
 id int 
)


insert into count_test values(1);
insert into count_test values(2);
insert into count_test values(null);

然后键入以下SQL进行查询,可以看到前面两条不会忽略null值,最后count(列名)会忽略null值。

select count(*),count(1),count(id) from count_test;

而性能在性能方面,很多人认为count(1)>count(*)>count(id)实际上前两者性能表现基本是一样的,按照《高性能MySQL》的说法:

通配符*并不会像我们所想的那样扩展成所有的列,实际上,它会忽略所有的列而返回统计的行数。

而count(1)传入的是常量,所以只做扫描行数,所以实际上性能表现为:count(1)≈count(*)>count(id)

如何定位慢查询SQL

针对慢SQL问题,如果业务上可以感知我们直接通过接口定位就好了,但是针对界面不可见的后端调度任务,就必须进行实时监控了。 要想定位慢查询SQL首先自然是要开启慢查询日志,对应的我们可以在my.cnf/my.ini中增加如下配置

[mysqld]
slow_query_log = 1
# 慢查询日志的位置
slow_query_log_file = /var/log/mysql/slow.log
# 最大时间阈值设置为5s
long_query_time = 5

后续想要获取慢查询的日志信息,我们可以通过如下指令导出,亦或者通过通过监控工具导出告警:

mysqldumpslow -s t /var/log/mysql/slow.log   # 按耗时排序
mysqldumpslow -s c /var/log/mysql/slow.log   # 按出现次数排序

而slow.log日志的内容,大体如下所示,对应字段含义分别是:

  • Query_time:查询耗时
  • Lock_time:等待表锁的时间
  • Rows_sent:返回给客户端的行数
  • Rows_examined:扫描了 50万行 数据

最后就是执行的SQL和时间:

# Time: 2023-10-05T12:34:56.789012Z
# User@Host: app_user[app_db] @  [10.0.0.2]
# Query_time: 5.123456  Lock_time: 0.002000 Rows_sent: 0  Rows_examined: 500000
SET timestamp=1696516496;
UPDATE products SET stock = stock - 1 WHERE product_id IN (SELECT product_id FROM orders WHERE order_date < '2023-01-01');

如果不用MySQL你会考虑用哪个数据库

优先考虑TIDB,这是一个具备关系型数据库和NOSQL数据库的优点,旨在提供高可用、强一致性的的分布式数据库,总的来说,它具备以下几个优点:

  • 支持水平拓展,Tidb可以通过增加节点实现扩展,支持大规模数据存储和高并发访问。
  • 数据库会自行完成分片并存储在不同节点上,避免我们业务逻辑上的分表的实现的复杂度。
  • TiDB支持ACID事务,确保数据一致性和完整性。
  • 它通过raft保证高可用和一致性。
  • 支持大多数MySQL的SQL语法。

使用MySQL主从架构时,需要注意那些问题

在进行分库分表时,我们必须结合硬件条件对应的MySQL压测结果针对业务需求评估资源,例如我们的业务需求要求QPS是10w,对应的数据库给定的服务器配置是4C8G,按照下图给出的压测报告,我们至少是需要30台(15台master和15台slave)数据库服务器保证高并发和高可用:

主从同步期间,要保证写操作都是在主库上,一旦写入操作不小心写入到从库,就会因为主从数据不一致导致bin.log同步复制数据中断。

本文地址:https://www.yitenyun.com/217.html

搜索文章

Tags

数据库 API FastAPI Calcite 电商系统 MySQL Web 应用 异步数据库 数据同步 ACK 双主架构 循环复制 Deepseek 宝塔面板 Linux宝塔 Docker 生命周期 序列 核心机制 esxi esxi6 root密码不对 无法登录 web无法登录 JumpServer JumpServer安装 堡垒机安装 Linux安装JumpServer Windows Windows server net3.5 .NET 安装出错 宝塔面板打不开 宝塔面板无法访问 SSL 堡垒机 跳板机 HTTPS 查看硬件 Linux查看硬件 Linux查看CPU Linux查看内存 无法访问宝塔面板 Windows宝塔 Mysql重置密码 HTTPS加密 连接控制 机制 ES 协同 Oracle 处理机制 Serverless 无服务器 语言 Spring SQL 动态查询 OB 单机版 scp Linux的scp怎么用 scp上传 scp下载 scp命令 运维 缓存方案 缓存架构 缓存穿透 技术 存储 索引 架构 InnoDB 响应模型 日志文件 MIXED 3 分页查询 Rsync 修改DNS Centos7如何修改DNS HexHub RocketMQ 长轮询 配置 监控 Redis 电商 系统 Linux 安全 服务器 聚簇 非聚簇 MySQL 9.3 数据 主库 异步化 防火墙 黑客 查询 group by sftp 服务器 参数 自定义序列化 数据库锁 SQLark PostgreSQL SQLite-Web SQLite 数据库管理工具 开源 存储引擎 管理口 业务 R edis 线程 线上 库存 预扣 Doris SeaTunnel MVCC 人工智能 向量数据库 推荐系统 加密 场景 共享锁 ​Redis 机器学习 推荐模型 流量 工具 PG DBA 数据备份 信息化 智能运维 网络架构 网络配置 AI 助手 Ftp redo log 重做日志 高可用 Canal B+Tree ID 字段 优化 万能公式 • 索引 • 数据库 RDB AOF Redis 8.0 GreatSQL 连接数 Postgres OTel Iceberg Python 缓存 核心架构 订阅机制 同城 双活 网络故障 云原生 INSERT COMPACT prometheus Alert Hash 字段 不宕机 自动重启 Web 微软 SQL Server AI功能 SVM Embedding IT运维 大模型 Netstat Linux 服务器 端口 引擎 性能 分库 分表 高效统计 今天这篇文章就跟大家 虚拟服务器 虚拟机 内存 向量库 Milvus OAuth2 Token Entity 开发 单点故障 DBMS 管理系统 MongoDB 容器 sqlmock 崖山 新版本 ZODB 容器化 LRU mini-redis INCR指令 JOIN Undo Log 数据集成工具 窗口 函数 悲观锁 乐观锁 openHalo SpringAI 分布式 集中式 磁盘架构 数据脱敏 加密算法 Redisson 锁芯 QPS 高并发 排行榜 排序 Testcloud 云端自动化 Redka Recursive 数据类型 PostGIS 意向锁 记录锁 EasyExcel MySQL8 聚簇索引 非聚簇索引 模型 启动故障 大表 业务场景 StarRocks 数据仓库 分页 数据结构 分布式架构 分布式锁​ Pottery 原子性 AIOPS R2DBC IT Caffeine CP MCP 开放协议 InfluxDB 1 网络 Web 接口 部署 RAG HelixDB 工具链 事务 Java 发件箱模式 SSH 数据分类 dbt 数据转换工具 池化技术 连接池 字典 filelock 对象 读写 速度 服务器中毒 事务隔离 传统数据库 向量化 优化器 单线程 Go 数据库迁移 仪表盘 双引擎 频繁 Codis 分页方案 排版 数据页 Order Crash 代码 线程安全 LLM List 类型 订单 事务同步 UUIDv7 主键 日志 Pump Ansible