ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

MySQL实战通关笔记:从安装配置到索引优化与故障排查

MySQL实战通关笔记:从安装配置到索引优化与故障排查 MySQL可以说是后端开发里绕不开的一道坎也是很多新人踏入数据世界的第一站。我自己刚开始接触MySQL时被安装配置、字符集、索引、存储过程这些东西磨得够呛踩过的坑能写满一页纸。所以这篇东西不是教科书式的概念罗列而是我这么多年实际用下来的一套“通关笔记”从环境装好、建库建表到SQL怎么写更稳、索引怎么建才不会翻车再到备份脚本、工具选择、故障排查一次讲清楚适合刚入门的同学也适合写了好几年SQL但一直靠“复制粘贴”活着的人。1. 先搞清楚MySQL到底在解决什么问题很多人装完MySQL就开始敲命令结果遇到一堆莫名其妙的问题归根结底是没搞明白它内部是怎么工作的。这节先花点时间把地基打牢。1.1 MySQL是什么为什么几乎所有后端项目都在用它MySQL是一个关系型数据库管理系统本质上就是帮你把数据存下来并且用结构化的方式去查询、更新、统计。你注册一个账号、下一个订单、发一条动态背后都是数据库在记录和返回数据。和文件存储相比数据库最大的优势在于数据有结构、查询有语法、并发有控制、异常有恢复。那为什么大量项目都选MySQL而不选别的我个人的看法是三个原因。第一开源免费社区庞大遇到问题搜索引擎一搜基本都有答案第二性能足够好配合InnoDB存储引擎在绝大多数业务场景下表现稳定第三生态成熟从主从复制到读写分离从备份工具到可视化客户端配套非常齐全。当然PostgreSQL、SQLite也有自己的优势比如SQLite适合嵌入式和小型工具PostgreSQL在复杂查询和地理信息上更强但MySQL赢在了“通用”两个字上尤其是互联网公司几乎默认它就是业务数据库的第一选择。1.2 MySQL的架构层次从一条SQL的旅行说起了解MySQL架构最好的方式是看一条SQL语句从客户端发出来之后到底经历了什么。整个过程大致是连接管理、解析优化、存储引擎。当你用命令行、Navicat或者程序里的连接池连上MySQL第一步是连接管理。MySQL会维护一个连接线程认证用户名密码校验权限。这里有个小知识连接不是无限制的max_connections默认值是151开发环境够用但线上高并发场景经常要调大配合连接池使用。连接建立之后SQL语句进入服务层先做词法分析和语法解析如果你把SELECT写成SELEC在这一步就会被拦住。解析通过后优化器开始发挥作用它决定用哪个索引、以什么顺序关联表、是否走临时表最后生成执行计划。这也是为什么有时候两条写法差不多的SQL执行时间天差地别往往就是执行计划不同。执行计划落到存储引擎层才是真正读写磁盘数据的地方。InnoDB是默认引擎负责事务、行锁、崩溃恢复。整个链路可以用一句话概括Server层负责“想清楚怎么做”存储引擎层负责“实际去做”。搞懂这个分层后面再看慢查询、死锁、锁等待思路会清晰很多。1.3 存储引擎怎么选InnoDB为什么是默认选项MySQL是支持多种存储引擎的存储引擎不同底层的存储机制、锁粒度、事务支持都不一样。常见的有InnoDB、MyISAM、MEMORY这几种。MyISAM是早期版本默认引擎特点是查询快、占用空间小但不支持事务也不支持行级锁表锁在写多场景下会非常难受。MEMORY是把数据放在内存里的引擎重启数据就没了只适合做缓存或临时表。而InnoDB之所以成为默认是因为它支持事务ACID、支持行级锁、支持崩溃后自动恢复同时通过聚簇索引和缓冲池把读性能也做到了很好。实际选择建议很简单没有特殊理由一律用InnoDB。我见过有人为了“省空间”把核心业务表改成MyISAM结果掉电后表损坏修复半天得不偿失。建表时可以显式指定引擎ENGINEInnoDB不写默认也是它。2. 环境准备把MySQL装起来并且能跑很多教程把安装一笔带过但说实话安装配置恰恰是劝退新手的重灾区。端口被占用、服务起不来、字符集乱码、路径有中文每个问题都能卡你半小时。这里把两种主流方式都讲清楚。2.1 10分钟装好MySQL 8.0压缩版安装全流程现在网上下载MySQL基本都能拿到8.0版本8.0.46是目前比较新的一个小版本。安装方式分两种安装包MSI和压缩版ZIP。我个人更推荐压缩版虽然步骤多一点但你能看到所有配置文件出了问题也知道去哪里排查而MSI安装包虽然自动化程度高但很多默认配置隐藏得很深。压缩版安装流程我整理成一套固定动作从MySQL官网下载ZIP压缩包注意区分32位和64位现在基本都是64位。解压到纯英文目录比如D:\mysql-8.0.46-winx64路径里千万不要有中文和空格。在解压目录下新建my.ini配置文件这是最关键的一步。以管理员身份打开命令行进入到bin目录执行mysqld --initialize-insecure初始化数据目录。执行mysqld --install把MySQL注册成Windows服务。执行net start mysql启动服务。用mysql -uroot -p登录因为用了--initialize-insecure初始密码为空直接回车就能进。my.ini里最核心的几项配置如下[mysqld] basedirD:/mysql-8.0.46-winx64 datadirD:/mysql-8.0.46-winx64/data port3306 character-set-serverutf8mb4 collation-serverutf8mb4_general_ci [client] default-character-setutf8mb4这里有几个细节容易出问题。basedir和datadir的路径分隔符建议用正斜杠/而不是反斜杠\反斜杠在INI文件里可能被当成转义符。port3306是MySQL默认端口如果被占用可以改成3307或者3308改完客户端连接时也要对应改。还有一个高频报错是“服务名无效”或者“启动停止”多数是服务没删干净试试用管理员身份在命令行执行sc delete mysql删掉旧服务再重新安装。初始化那一步--initialize-insecure会给root一个空密码适合本机学习直接登录如果你用--initialize系统会生成一个随机密码第一次登录后必须自己改。忘了密码也别慌后面第6章有专门的处理方案。2.2 Docker部署MySQL适合开发环境的快捷方式如果你用的是Linux或者Mac又或者是装了Docker Desktop的Windows其实还有一个更干净的方案用Docker跑MySQL。好处是环境隔离不会污染宿主机也不会遇到“我卸载了MySQL为什么端口还开着”这种问题。最简启动命令是这样docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD123456 \ -e TZAsia/Shanghai \ -v /my/own/datadir:/var/lib/mysql \ mysql:8.0解释一下几个关键参数-p 3306:3306是把容器内3306端口映射到宿主机的3306左边是宿主机端口右边是容器端口MYSQL_ROOT_PASSWORD是初始化时设置的root密码-v是数据目录的挂载这一步千万不能省否则容器删了数据就全没了。Docker方式最大的价值在于随时可以docker rm -f mysql8删掉重来适合练习和学习也适合本地起多个不同版本的MySQL做对比测试。但线上生产环境用Docker跑MySQL要额外考虑数据持久化、网络性能、日志收集等问题新手阶段不用太纠结先把本地方便跑起来这件事做好。2.3 新手最容易踩坑的5个配置项装好之后别急着写SQL先检查几个配置不然以后数据量上来或者换环境部署时你会被各种诡异问题折磨。我整理了一张自检表都是我平时排查时经常看的配置项默认值建议原因character-set-serverlatin1utf8mb4默认字符集不支持完整中文和表情符号线上乱码多半是这里没改collation-server随字符集utf8mb4_general_ci决定字符串比较规则影响大小写敏感和排序max_connections151视情况调大高并发下连接数不够会直接报Too many connectionssql_mode宽松模式根据业务设置控制是否允许零日期、是否严格校验数据default-time-zone系统时区08:00时区不对会导致时间字段差8小时排查起来非常隐蔽其中字符集和排序规则值得多说两句。MySQL 8.0默认字符集其实已经是utf8mb4了但老版本的库表可能还是latin1迁移数据后中文直接显示成问号。判断当前配置可以执行SHOW VARIABLES LIKE character_set%;看到character_set_server是utf8mb4就基本安全。另外排序规则里的后缀含义要能看懂_ci是case insensitive不区分大小写_cs是case sensitive区分大小写_bin是按二进制比较最严格。新手总问“为什么我查大写A能查到小写a”答案就在这个规则里。3. 建库建表与高频SQL操作环境搞定之后真正的数据库基本功从这里开始。建库建表是地基SQL语句是日常工具这一章我会直接用能抄走的例子讲顺便把一些容易犯糊涂的细节点透。3.1 一套能直接抄作业的建库建表SQL建库之前先想清楚字符集省的后面改来改去CREATE DATABASE shop DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE shop;建表语句我拿一个最典型的用户表做示范CREATE TABLE user ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主键, username VARCHAR(50) NOT NULL COMMENT 用户名, password VARCHAR(100) NOT NULL COMMENT 密码加密后的, email VARCHAR(100) DEFAULT NULL COMMENT 邮箱, age TINYINT UNSIGNED DEFAULT 0 COMMENT 年龄, status TINYINT NOT NULL DEFAULT 1 COMMENT 状态1正常 0禁用, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表;这张表里有几个习惯是我一直坚持的。第一主键用BIGINT UNSIGNED AUTO_INCREMENT不用业务字段做主键因为自增主键在InnoDB里插入效率最高而且业务字段随时可能变化。第二每个字段都写注释过三个月你再回来看这张表一定会感谢自己。第三create_time用默认值CURRENT_TIMESTAMPupdate_time用ON UPDATE CURRENT_TIMESTAMP插入和更新时完全不用手动维护时间字段。第四状态字段用数字而不是字符串虽然可读性差一点但查询性能更好配合注释也不影响理解。3.2 增删改查的进阶姿势UPDATE语法与子查询更新增删改查是SQL的基本功SELECT、INSERT、DELETE、UPDATE这四个命令谁都会写但“会用”和“用得稳”是两回事。这里重点讲几个容易出问题的地方。首先是UPDATE语句的标准语法UPDATE user SET age 18, status 1 WHERE id 5;这里的关键是WHERE条件。执行UPDATE之前强烈建议先跑一遍相同条件的SELECT确认范围然后再执行更新。我见过太多人在生产环境上执行UPDATE user SET status 0忘了加WHERE结果全表都被更新了。这不是段子这是每天都在发生的事故。再说一个比较进阶的用法用子查询更新数据热搜词里“MySQL中更新子查询”指的就是这个。比如我想把“没有任何订单的用户”标记为禁用可以这样写UPDATE user SET status 0 WHERE id NOT IN ( SELECT user_id FROM orders );但这里有一个著名的坑MySQL不允许在UPDATE语句中直接修改“正在被查询的表”。比如你想把所有用户的订单数更新到用户表的order_count字段下面的写法会报错UPDATE user SET order_count ( SELECT COUNT(*) FROM orders WHERE orders.user_id user.id );如果orders表里有外键指向user表并且这条语句被MySQL判定为“同一张表的更新”就会报You cant specify target table user for update in FROM clause。解决方案是套一层临时表UPDATE user SET order_count ( SELECT cnt FROM ( SELECT user_id, COUNT(*) AS cnt FROM orders GROUP BY user_id ) AS tmp WHERE tmp.user_id user.id );这种“包一层子查询”的技巧在复杂统计场景下非常实用建议直接收藏。3.3 字段默认值、NULL与整数溢出那些“小问题”的真相有时候SQL语句本身没写错但结果就是不对问题往往出在数据类型和默认值上。这里说三个我实际工作中碰到的典型情况。第一个是设置默认值为0。热搜里有“mysql设置默认值为0”我估计是有人建了age INT DEFAULT 0但插入数据时发现还是NULL。原因通常是字段没写NOT NULL或者你的插入语句显式写了NULL进去了。DEFAULT只在“插入时没给这个字段值”的情况下生效如果你写了INSERT INTO user (age) VALUES (NULL)那它存进去的就是NULL。解决办法是建表时把字段定义为age TINYINT UNSIGNED NOT NULL DEFAULT 0从源头堵死NULL。第二个是整数溢出问题。热搜里“mysql中int5”这个关键词可能是在问INT类型做加法时为什么报错或者结果不对。INT的取值范围是 -2147483648 到 2147483647加5本身没问题但如果字段里存的值已经接近上限再加就会溢出或者被截断。比如BIGINT用UNSIGNED时范围是0到18446744073709551615UNSIGNED BIGINT 5在超过上限时MySQL会直接报BIGINT value is out of range的错误。解决方案是统计计数、金额、主键这类可能变大的数值优先用BIGINT不要图省事用INT。第三个是DATETIME和TIMESTAMP的选择。DATETIME范围更大不受时区影响TIMESTAMP会跟随会话时区转换范围只有1970到2038年。日常开发我用DATETIME居多除非确定需要自动转时区。3.4 修改表结构的正确打开方式业务上线后表结构基本一定会变加字段、改类型、加索引都是家常便饭。这里必须学会的就是ALTER TABLE。常用操作整理如下-- 添加字段 ALTER TABLE user ADD COLUMN nickname VARCHAR(50) DEFAULT NULL COMMENT 昵称; -- 删除字段 ALTER TABLE user DROP COLUMN nickname; -- 修改字段类型 ALTER TABLE user MODIFY COLUMN age SMALLINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 年龄; -- 修改字段名称和类型 ALTER TABLE user CHANGE COLUMN age user_age INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 用户年龄; -- 添加索引 ALTER TABLE user ADD INDEX idx_email (email); -- 添加唯一索引 ALTER TABLE user ADD UNIQUE KEY uk_email (email);这里有几个要注意的点。MODIFY和CHANGE的区别是CHANGE可以同时改字段名和类型而MODIFY只能改类型和属性如果你只想改类型用MODIFY改完名字变了别人查不到那就是事故。修改表结构时MySQL会根据情况重建表大表上执行可能锁表很久线上操作要考虑在低峰期进行或者用专门工具平滑处理。4. 索引与查询优化索引是MySQL里性价比最高的性能优化手段也是面试必问。但索引不是建了就完事用不对反而拖慢写入速度。这一章重点讲清楚怎么建索引以及哪些操作会导致索引失效。4.1 索引创建与使用为什么单表查询还是慢大家最常问的一个问题是我明明在字段上建了索引为什么查询还是很慢先看看索引到底怎么建。普通索引、唯一索引、联合索引是最常用的三类-- 普通索引 CREATE INDEX idx_email ON user(email); -- 唯一索引字段值不能重复 CREATE UNIQUE INDEX uk_username ON user(username); -- 联合索引 CREATE INDEX idx_status_create_time ON user(status, create_time);索引的核心原理可以理解成书的目录没有目录你得翻遍整本书才能找到内容这叫全表扫描有了目录直接翻到那一页就行这就是索引查找。但在实际使用中索引经常“失效”最常见的几个姿势在索引列上做函数运算比如WHERE YEAR(create_time) 2024这会导致索引失效正确写法是WHERE create_time 2024-01-01 AND create_time 2025-01-01。隐式类型转换比如字段是字符串varchar你却拿数字去查WHERE mobile 13800000000MySQL会把字段转成数字再比较索引失效。使用LIKE %xxx前导百分号导致无法走索引。联合索引不满足最左前缀原则比如索引是(status, create_time)你只查create_time走不了索引必须先有status条件。第二个问题的经典案例我遇到过很多次。热搜里“mysql设置唯一已经有重复数据库”意思是给已有重复数据的字段加唯一索引时直接报错Duplicate entry xxx for key。解决办法是先把重复数据处理掉再添加唯一索引。可以先查重复数据SELECT username, COUNT(*) FROM user GROUP BY username HAVING COUNT(*) 1;然后决定是删除重复记录还是把重复值更新成不同值处理干净之后索引才能建上。这说明一个道理建索引之前先确认数据本身满足约束条件。4.2 排序、大小写敏感与字符集影响结果的三件小事排序也是MySQL里高频使用却容易踩坑的点。ORDER BY有两种实现方式Using index和Using filesort。走索引排序性能最好但前提是排序字段在索引中。如果你的排序字段没索引MySQL会把结果集读到内存或磁盘上排序数据量大时慢得离谱。排查排序问题最直接的方法是看执行计划当Extra列出现Using filesort时就要考虑给排序字段加索引或者调整查询结构。大小写敏感问题在热搜里出现了两次“kingbase mysql模式字符串不区分大小写咋回事”和“mysql自动忽略大小写”。MySQL默认的排序规则是utf8mb4_general_ci重点就在最后两个字母ci上代表不区分大小写。所以查询WHERE username admin时Admin、ADMIN都会被匹配到这在登录验证场景可能引发安全问题建议在代码层处理或者把字段排序规则改成utf8mb4_binALTER TABLE user MODIFY COLUMN username VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;这样等于让MySQL按二进制值比较admin和Admin就是两条完全不同的数据。另外还有一个相关配置是lower_case_table_names它决定数据库名和表名是否区分大小写。1代表不区分0代表区分这个配置在Windows和Linux上的表现不一样跨环境部署时一定要统一否则你本地开发好好的一上Linux服务器就报“表不存在”。4.3 EXPLAIN查看执行计划学会自己找索引问题遇到慢查询第一反应不要是加索引而是先看执行计划。MySQL提供了一条非常实用的命令EXPLAIN SELECT * FROM user WHERE status 1 ORDER BY create_time DESC;输出结果里重点关注这几个字段。type是访问类型最好的是const、eq_ref、ref一般的是range、index最差的是ALL出现ALL代表全表扫描。key显示实际用到的索引如果为NULL说明没走索引。rows是预估扫描行数越小越好。Extra里如果出现Using filesort或者Using temporary都说明需要优化。有一句口诀我一直告诉身边的人看type、看key、看rows、看Extra。这四个字段能覆盖90%的慢查询排查场景。比如一条查询typeALL, rows1000000, ExtraUsing filesort那你基本不用犹豫要么条件字段缺索引要么排序字段没被索引覆盖。5. 存储过程、自动备份与常用工具基础SQL写熟练之后有一些能明显提升效率的工具和脚本值得掌握。比如存储过程处理重复逻辑、bat脚本做自动备份、可视化工具辅助排查问题。这些内容不复杂但在实际工作和面试里都很加分。5.1 存储过程的创建与错误处理存储过程就是把一段SQL逻辑封装起来像写函数一样去调用。好处是复用性强逻辑集中在数据库端坏处是维护成本高依赖数据库本身。我的建议是简单统计可以写存储过程复杂业务逻辑还是放在应用层。先看一个最简单的存储过程长什么样DELIMITER $$ CREATE PROCEDURE get_user_count(OUT total INT) BEGIN SELECT COUNT(*) INTO total FROM user; END$$ DELIMITER ;解释一下。DELIMITER $$是为了告诉MySQL存储过程内部的;不是完整语句的结束符真正的结束符是$$。定义完之后用CALL get_user_count(count)调用再用SELECT count查看结果。存储过程中经常需要处理重复键、数据不存在等错误这时可以用DECLARE CONTINUE HANDLER来捕获DELIMITER $$ CREATE PROCEDURE insert_user_with_log(IN p_username VARCHAR(50)) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT error AS result; END; START TRANSACTION; INSERT INTO user(username) VALUES (p_username); COMMIT; SELECT success AS result; END$$ DELIMITER ;这个例子演示了事务和异常处理的组合写法一旦INSERT报错自动回滚并返回error标识。实际项目里存储过程里的错误信息一般会记录到日志表排查问题时会方便很多。注意定义处理器的顺序必须在存储过程内其他语句之前否则MySQL会报语法错误。5.2 用bat脚本实现MySQL自动备份数据备份这件事平时没人觉得它重要直到某天误删了表才追悔莫及。我强烈建议每个人从第一天就给自己的MySQL配上自动备份。最简单靠谱的方式是Windows计划任务加bat脚本。脚本核心就一行用mysqldump导出echo off set backup_dirD:\mysql_backup set mysql_dirD:\mysql-8.0.46-winx64\bin set db_nameshop set date_str%date:~0,4%%date:~5,2%%date:~8,2% set backup_file%backup_dir%\%db_name%_%date_str%.sql %mysql_dir%\mysqldump -uroot -p123456 --default-character-setutf8mb4 --single-transaction --routines --events %db_name% %backup_file%几个参数说明一下。--single-transaction是InnoDB表的在线备份方式不会锁表导出过程中数据还能正常读写--routines会带上存储过程和函数--events带上事件调度器任务。%date%在Windows下取日期字符串不同系统格式可能有差异最好先输出来看一下今年是哪一位避免文件名乱掉。备份策略建议是每天备份一次全量保留最近7天或30天的文件。保留策略可以再加一段删除旧文件的逻辑forfiles /p %backup_dir% /s /m *.sql /d -7 /c cmd /c del path配置好之后打开Windows的“任务计划程序”创建基本任务选择每天凌晨2点执行这个bat文件就能实现无人值守自动备份。恢复的时候执行mysql -uroot -p shop D:\mysql_backup\shop_20250101.sql这条命令会把SQL文件里的建表语句和数据INSERT语句重新执行一遍完成恢复。备份文件建议定期复制到另一台机器或者云存储防止服务器磁盘损坏导致备份一起丢失。5.3 Workbench与Navicat怎么选常用功能对照命令行虽然很酷但日常开发里可视化工具能大幅提升效率。最常用的两个是MySQL官方自带的MySQL Workbench和商业软件Navicat。先说说我自己的使用习惯看简单的数据用Workbench因为免费装MySQL的时候可以一起装上做复杂的库表设计、数据迁移、结构对比时用Navicat因为功能更全。功能MySQL WorkbenchNavicat价格免费付费有试用版连接管理支持界面简洁支持可分组管理查询编辑器支持自动提示支持自动提示与代码片段数据导入导出有CSV、SQL等格式格式更多支持Excel表结构设计可视化设计能生成SQL可视化设计更顺手数据同步支持支持功能更强大中文乱码处理偶尔需要手动设置连接配置里可调编码不管用哪个工具有几个公共的注意点。连接MySQL时要选好字符集一般用utf8mb4否则中文显示乱码执行UPDATE和DELETE之前养成先选中查询、后执行的习惯避免误点执行全表操作连接生产环境时确认自己有没有足够的权限不要拿着root到处跑。还有一点想提醒大家无论工具有多方便SQL基础命令必须会因为线上排查很多时候没有图形界面只给你一个终端窗口。工具是帮你加速的不是让你依赖的。6. 常见问题排查与面试考点最后这章我整理了一些实际工作中反复遇到的故障处理思路和面试常考点希望能帮你少走点弯路。6.1 忘记密码、连接失败、sqoop连不上3个高频故障处理第一个高频故障是忘记root密码。处理思路是跳过权限验证启动MySQL再重置密码。以Windows环境为例先停止MySQL服务然后用--skip-grant-tables方式启动net stop mysql mysqld --skip-grant-tables再用另一个命令行窗口无密码登录mysql -uroot执行FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED BY new_password;改完重启服务密码就生效了。注意--skip-grant-tables模式非常危险只有本机排查时临时使用操作完必须重启恢复绝不能长期开启。第二个高频故障是连接失败报Cant connect to MySQL server。排查顺序是先确认服务是否启动net start mysql再确认端口是否监听netstat -ano | findstr 3306然后确认防火墙是否放行3306端口最后确认连接地址和账号权限。通常90%的问题出在这四个环节之一。第三个相对冷门但面试里出现过Sqoop连接不上MySQL。Sqoop是数据迁移工具连接失败大概率是驱动问题或者主机权限问题。检查清单包括JDBC驱动jar包是否放在正确目录、MySQL是否允许远程连接、账号是否有远程访问权限、端口是否通。另外MySQL 8.0的加密方式变了需要在连接串里加上?useSSLfalseallowPublicKeyRetrievaltrue否则会握手失败。6.2 常用命令速查与面试高频题面试MySQL绕不开的问题基本就那几个。一个是索引底层数据结构为什么选B树而不是二叉树或者哈希回答要点是B树矮胖、叶子节点有序、支持范围查询、磁盘IO少。一个是事务隔离级别MySQL默认是REPEATABLE READInnoDB通过MVCC和间隙锁解决了幻读问题。一个是SQL执行顺序FROM、ON、JOIN、WHERE、GROUP BY、HAVING、SELECT、DISTINCT、ORDER BY、LIMIT这个顺序可以背下来面试官很喜欢穿插问。平时开发常用的命令再集中列一份速查表操作命令查看所有数据库SHOW DATABASES;切换数据库USE dbname;查看所有表SHOW TABLES;查看表结构DESC tablename;查看创建表SQLSHOW CREATE TABLE tablename;查看所有进程SHOW PROCESSLIST;查看当前版本SELECT VERSION();开启事务START TRANSACTION;提交事务COMMIT;回滚事务ROLLBACK;6.3 一套自查清单给你的MySQL做个“体检”文章最后把我平时给MySQL做“体检”的思路分享出来。不管你是刚装完库还是系统跑了一段时间都建议按这套思路检查一遍。第一查字符集执行SHOW VARIABLES LIKE character_set%;确认所有项都包含utf8mb4数据库、表、字段的字符集可以逐个查看防止出现三级不一致。第二查时区执行SHOW VARIABLES LIKE time_zone;如果是SYSTEM建议显式设置成08:00避免一天后发现所有时间字段都差8小时。第三查慢查询日志执行SHOW VARIABLES LIKE slow_query_log%;打开慢查询日志设置long_query_time1以后超过1秒的SQL都会被记录这是排查性能问题最直接的入口。第四查连接数SHOW STATUS LIKE Threads_connected;如果接近max_connections就要考虑优化连接池配置或调整上限。第五查表碎片执行SHOW TABLE STATUS FROM dbname LIKE tablename\G;看Data_free字段数值大说明碎片多可以执行OPTIMIZE TABLE tablename;整理。这套体检我每次上线前都会做一遍成本很低但能提前发现很多隐患。MySQL这东西说难不难说简单也不简单关键是养成好习惯数据操作前确认条件、结构变更前备份数据、上线前检查配置。把每一步都做扎实了数据库大概率不会给你惹麻烦。
返回列表