• MySQL 基础知识点小结

MySQL 基础知识点小结

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

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