资讯详情

资讯详情

数据库性能优化实战:从SQL调优到Windows批处理脚本

刚开始做“与AI英语”这个系列的时候我没想到会坚持到第四天。今天的标题是数据库与性能优化也是我近期工作里刚好在啃的一块硬骨头。用AI辅助学英语这个形式最大的好处就是能把枯燥的技术文档变成双语的、带语境的学习材料不光是背单词而是真的能在阅读和表达里遇到它们。今天这一篇我把数据库的核心概念、性能优化思路以及几个热门搜索里经常被问到的实操场景整理成一份可以直接参考的笔记同时也把我在学习过程中的方法分享出来给同样在坚持打卡的朋友一点参考。1. 学习场景搭建AI辅助下的双语技术学习1.1 为什么选择数据库与性能优化作为英语学习素材很多人在英语学习和技术学习之间找不到结合点搞得两边都很痛苦。我自己试下来最有效的办法就是直接用技术内容当语料。数据库和性能优化这个主题中英文资料都极其丰富从官方文档到社区帖子随便一个关键词都能捞出一大片高密度术语材料特别适合用来做上下文记忆。举个例子今天我看资料时频繁出现的几个术语Database Connection Pool数据库连接池Query Optimization查询优化Index Maintenance索引维护Deadlock死锁Transaction Isolation Level事务隔离级别如果只是孤立地学这些词转头就忘。但放到具体的句子里就很容易形成记忆锚点。AI在这里扮演的角色是“贴身助教”——我可以让它把一段英文文档翻译成中文再反过来把中文场景翻译成英文然后对照校验自己哪儿理解偏了哪儿用词不够地道。1.2 实际操作方法让AI生成可对照学习的资料我通常是这样操作的先让AI用英文生成一段关于某个技术点的解释然后自己尝试用中文复述再让AI把我的中文翻译回英文看差距在哪儿。以“数据库索引”为例我让AI给了三个层次的输出英文原版解释、中文要点概括、中英术语对照表。英文原版解释大概是这样的An index is a data structure that improves the speed of data retrieval operations on a database table at the cost of additional writes and storage space. Proper index design requires understanding the query patterns and the selectivity of columns.这个过程中AI还能顺手标注生词和短语比如“data structure”数据结构、“retrieval operations”检索操作、“selectivity of columns”列的区分度比干背单词书有用得多。1.3 给自己定一个“可输出”的学习指标学习语言最怕的是一看就会、一开口就废。我给这个系列定的规矩是每天学到的知识必须能写出一段“英文小结”字数不用多150到200词就够。内容是用英文解释今天学到的核心概念AI负责改错和润色。今天我在打卡记录里写的是Today I focused on database performance. The most important takeaway is that indexing speeds up SELECT operations but slows down INSERT and UPDATE. So the key is to balance between read performance and write overhead.AI把“speeds up SELECT operations”保留但改成了“can dramatically improve the speed of read operations”这样的表达也提醒我“write overhead”这个短语在数据库语境下更常见的说法是“write amplification”。这个纠错过程本身就值回时间了。2. 数据库核心知识梳理从增删改查到事务并发2.1 SQL基础与增删改查数据库的CRUD操作是基本功但在性能优化的语境下每个操作都有讲究。网上常看到“数据库增删改查”这个热搜词看起来简单其实里面每个环节都有性能陷阱。以查询为例最典型的坑就是SELECT *。从性能角度看这会让数据库把所有字段都读出来浪费IO带宽。正确做法只查需要的列。但如果字段确实很多还是全查就要看有没有覆盖索引帮忙兜底。再比如INSERT一次插一条和一次插一千条性能差距是数量级的。批量插入时很多数据库支持multi-row insertMySQL里写成INSERT INTO orders (id, user_id, amount) VALUES (1, 1001, 99.00), (2, 1002, 129.00), (3, 1003, 199.00);一条SQL搞定比循环一千次单条INSERT快很多。原因是减少了SQL解析、网络往返、日志写入的次数。2.2 索引原理为什么查询快但写入慢索引的核心机制就是拿空间换时间。数据库每次用索引查数据时实际上是先查B树结构找到主键或行指针再回表拿完整数据。这比全表扫描快得多尤其在大表上效果特别明显。但索引不是越多越好。每建一个索引插入和更新的时候就要额外维护这个索引结构。我见过一个项目数据库里一张表建了十几个索引结果写操作越来越慢单次插入从几毫秒涨到了几十毫秒。后来一看监控发现大部分时间都耗在了索引维护上。这就是典型的“索引过多导致写入性能下降”。所以判断一个索引该不该建核心看两个东西查询频不频繁列的区分度高不高。性别这种列区分度极低索引基本没用。而订单号、用户ID这种列数据唯一性好就是索引的优质候选。2.3 事务ACID与隔离级别事务是数据库保证数据正确性的核心机制。ACID四个特性——原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability每个都对应了底层的一套实现机制。在性能优化里面和ACID关系最密切的是隔离级别。默认的隔离级别越高并发控制就越严格相应地性能就越受限。以MySQL的InnoDB为例默认隔离级别是Repeatable Read可重复读Oracle默认是Read Committed读已提交SQL Server默认也是Read Committed。隔离级别不同直接导致脏读、不可重复读、幻读这些问题是否出现。这里的性能权衡是隔离级别越高锁的粒度越粗、持锁时间越长并发能力越差。所以生产环境中很多团队会把隔离级别调低一档来换吞吐量前提是业务能接受相应的数据一致性风险。2.4 锁机制与死锁排查锁是为了控制并发访问。行锁、表锁、间隙锁每种锁都有自己适用的场景和坑。最让人头疼的就是死锁Deadlock尤其在多个事务以不同顺序更新相同行的时候特别容易触发。排查死锁时第一件事不是乱试方案而是先看数据库的错误日志。MySQL里执行SHOW ENGINE INNODB STATUS;可以看到最近一次死锁的详细信息包括涉及的事务、锁等待的资源、持有的锁等。有了这些信息再去调整业务代码里的加锁顺序问题通常能解决七八成。还有一个经验是尽量让事务保持短小精悍不要在事务里做耗时的外部调用比如发HTTP请求、查询远程接口。事务时间越长锁持有的时间就越长死锁和锁等待的概率就越大。2.5 连接池数据库资源管理的命门数据库连接池这个热搜词热度一直不减因为很多线上故障都是连接池配置不当引起的。连接池的作用是复用数据库连接避免频繁建立和销毁连接带来的开销。但这个池子的参数如果设错了麻烦非常大。关键参数有几个最小空闲连接数池里常驻保持的最小连接数设太小的话高峰期得现建连接。最大连接数池子里最多同时能有多少连接。这里不是越大越好连接数过高会耗尽数据库服务器的线程资源、内存反而拖垮性能。连接超时时间从池子里获取连接时如果等待时间超过了超时值就会抛异常。实际项目中一个常见的建议是最大连接数不要设置得像开Party那么随意要先压测再根据数据库的CPU、内存、磁盘IO表现来定。比如一个8核32G的MySQL实例并发连接数压到100左右性能往往还行但如果压到500可能直接触发线程调度和上下文切换的瓶颈。3. 性能优化关键环节分析从SQL到数据库选型3.1 SQL优化从慢查询日志开始做SQL优化第一步永远是找到慢查询。MySQL里可以通过慢查询日志来定位配置文件里开启slow_query_log 1 slow_query_log_file /var/log/mysql/slow.log long_query_time 1这样执行时间超过1秒的SQL都会被记录下来然后再用EXPLAIN逐条分析执行计划。EXPLAIN看什么最重要的一列是type它表示访问表的方式。all代表全表扫描就差的意思ref和eq_ref是索引查询效率较高。还有key列看实际用到了哪个索引rows列估算扫描的行数数值越小通常越好。举一个典型的优化案例。我处理过一条报表统计SQL原来执行要3秒多EXPLAIN显示全表扫描过滤条件里的字段没有索引。后来在查询条件涉及的列上加了联合索引执行时间直接降到70毫秒效果立竿见影。这就是索引在SQL优化中的首要地位。3.2 缓存策略减少数据库压力的有效手段性能优化进行到一定阶段光靠调SQL已经不能满足要求了这时候就要引入缓存。缓存的本质很简单把高频访问、变动不频繁的数据放到内存里减少数据库的重复计算和查询压力。常见的缓存层次有应用本地缓存如Caffeine、Guava Cache分布式缓存如Redis、Memcached数据库内部的查询缓存现代数据库大多不推荐因为维护成本高缓存设计里最核心的问题是缓存一致性。比如用户更新了资料如果只更新数据库没更新缓存用户读到的还是旧数据。这个问题的常见解法是Cache Aside Pattern读的时候先查缓存查不到再查数据库并回填缓存写的时候先更新数据库再删除缓存。热点数据还要考虑缓存穿透、缓存击穿、缓存雪崩。穿透是因为查询了不存在的key每次都会打到数据库这时可以用布隆过滤器或空值缓存解决。雪崩是大批量缓存同时过期导致数据库瞬时压力暴增解决办法是过期时间加随机值避免集中失效。3.3 数据库选型关系型、向量数据库与新型数据库近年来数据库选型的热度一直很高热搜词里面“达梦数据库”“人大金仓数据库”“clickhouse”“向量数据库”“sqlite数据库”这些都常被搜到。先说说关系型数据库。Oracle、MySQL、SQL Server、达梦这几个核心都是关系模型靠SQL操作。Oracle胜在稳定和功能全适合企业级核心业务MySQL凭借开源、轻量、生态好成了互联网行业的主力达梦和金仓作为国产数据库信创和国企项目里用得越来越多它们在语法上和Oracle、PostgreSQL兼容度比较高迁移成本是一个关键考虑。然后是SQLite。这是一个嵌入式数据库不需要独立服务进程适合移动端、本地工具。今年“flutter 内嵌数据库”“python sqlite”这些词经常被一起搜到说明大家都在做本地数据存储和同步的方案。SQLite性能表现不差只是并发写能力有限不适合多进程同时大量写。ClickHouse是我今年比较关注的开源列式数据库专门做OLAP。对超大数据集的聚合分析查询ClickHouse比传统行式存储数据库快一个数量级。原因是列式存储只读取查询涉及的列加上压缩率高、物化视图等特性适合写报表、做用户行为分析这类场景。Vector Database向量数据库最近也是非常热门的方向。AI智能体的企业知识库、RAG检索增强生成应用里知识片段被向量化之后存进向量数据库通过相似度检索找出最相关的内容。常见的选项有Milvus、Pinecone、Qdrant也有Redis这种传统缓存扩展出向量能力的方案。和一些团队闲聊时大家提到的点是向量数据库不能盲目照搬关系型数据库的建模思路要重点考虑embedding维度、索引类型如HNSW和召回率。3.4 数据库迁移与数据导入的实战心得热搜词里有“clickhouse数据库整体迁移”“excel导入数据库”“docker 内部iserver如何连接达梦数据库”这几个场景我或多或少都碰过。ClickHouse迁移和MySQL这类事务性数据库不一样数据量大、节点多直接导出再导入很可能慢到怀疑人生。常用思路是用ClickHouse自带的remote表函数做分布式拷贝或者用clickhouse-copier工具。如果数据量达到TB级那就要设计分片迁移和校验方案逐批同步。Excel导入数据库也是个高频需求。最稳妥的做法是不要直接操作Excel文件而是先转成CSV或Parquet再用数据库的批量导入命令。MySQL里用LOAD DATA INFILE比逐行INSERT快很多。需要注意字符集问题CSV文件是UTF-8Excel可能是GBK导入前最好统一转换否则会出现乱码。Docker里连接达梦数据库这个问题核心是网络配置。达梦的Docker镜像默认端口是5236如果容器和宿主机隔离网络要用--network host或者端口映射。很多报错其实是端口不通或者防火墙拦截导致的不是数据库自身的问题。排查时先ping通网络再检查端口监听最后才是看用户名密码和权限。3.5 MySQL具体场景修改表结构耗时怎么破“mysql数据库修改结构”也是热搜词这个坑我踩过不止一次。对一个几千万行的表做ALTER TABLE ADD COLUMN默认情况下MySQL会复制整张表的数据到新表期间全程锁表业务基本停摆。这个在MySQL 5.6以前尤其明显后来有了Online DDL有些操作可以避免复制全表但依然有局限。现在常用的方案是低峰期操作减少对线上业务的影响。用pt-online-schema-change这类在线变更工具它通过触发器同步增量数据把变更过程对业务的影响降到最低。拆分多次变更避免一条ALTER里面同时做太多操作导致锁持时间过长。另外提一句表结构变更后记得重建相关索引尤其是新增了字段之后原有的联合索引可能需要调整。4. 实操环节Windows游戏性能优化的BAT批处理脚本热搜词里有一条非常具体的需求“请帮我生成一段 bat 批处理代码用于优化 windows 系统的游戏性能包括关闭不必要的后台服务、调整电源模式为高性能、优化网络延迟、清理系统临时文件。”这个我来满足一下顺便拆解一下每个步骤的原理。4.1 脚本正文echo off :: 需要管理员权限运行 :: Batch Script for Windows Game Performance Optimization echo echo Windows Game Performance Optimizer echo echo. :: ---------- 1. Set Power Scheme to High Performance ---------- echo [1/5] Setting power scheme to High Performance... powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c echo Done. echo. :: ---------- 2. Disable Unnecessary Services ---------- echo [2/5] Disabling unnecessary services... :: SysMain (Superfetch) - sometimes heavy on HDD sc config SysMain start disabled nul 21 net stop SysMain nul 21 :: Windows Search - can be a resource hog during gaming sc config WSearch start disabled nul 21 net stop WSearch nul 21 :: Print Spooler - not needed if no printer sc config Spooler start disabled nul 21 net stop Spooler nul 21 echo Done. echo. :: ---------- 3. Optimize Network Latency ---------- echo [3/5] Optimizing network latency... :: Disable Nagles Algorithm for lower latency reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings /v TcpNoDelay /t REG_DWORD /d 1 /f :: Increase QoS scheduling priority reg add HKLM\SOFTWARE\Policies\Microsoft\Windows\Psched /v NonBestEffortLimit /t REG_DWORD /d 0 /f echo Done. echo. :: ---------- 4. Clean Temporary Files ---------- echo [4/5] Cleaning temporary files... :: User Temp folder del /q /f /s %TEMP%\* nul 21 :: Windows Temp folder del /q /f /s C:\Windows\Temp\* nul 21 :: Prefetch folder del /q /f /s C:\Windows\Prefetch\* nul 21 echo Done. echo. :: ---------- 5. Set Game Priority to High ---------- echo [5/5] Registry tweak for GameDVR disabled... reg add HKCU\System\GameConfigStore /v GameDVR_Enabled /t REG_DWORD /d 0 /f reg add HKCU\Software\Microsoft\Windows\CurrentVersion\GameDVR /v AppCaptureEnabled /t REG_DWORD /d 0 /f echo. echo All done! Please restart your computer for the changes to fully take effect. pause4.2 各步骤原理与注意事项第一步电源模式设置为高性能。Windows默认的均衡模式会根据负载动态调整CPU频率这在游戏场景中经常表现为“关键帧卡顿”。高性能模式把CPU最低和最高处理器状态都拉到100%让CPU保持高频。8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c是高性能模式的GUID这个值是固定的不用自己查。但这里要提醒笔记本用户谨慎使用高性能电源模式因为会让风扇持续狂转电池续航直线下降。台式机的话问题不大。第二步关闭后台服务。脚本里关了SysMain旧称Superfetch、Windows Search和Print Spooler。SysMain这个服务在机械硬盘上有时会高频读写导致磁盘占用100%。关掉之后很多老机器立刻感觉“变轻”了。但如果你用的是大内存的SSDSysMain反而可能帮忙预加载常用应用所以关不关要看具体配置。Windows Search主要影响的是文件索引关了之后搜索文件会变慢但对游戏没啥影响。Print Spooler就不用说了没打印机纯属浪费资源。第三步网络延迟优化。这里主要做的是禁用Nagle算法。Nagle算法的目的是减少小数据包数量把多个小包合并成大包发送以提升网络吞吐。但代价就是延迟变高对FPS、MOBA这类实时性要求高的游戏来说这个延迟非常致命。TcpNoDelay这个注册表项可以绕过Nagle算法每个包都立即发送。QoS调度那里NonBestEffortLimit设为0意味着系统保留带宽限制降为0理论上可以给游戏让出更多网络资源。实际上Windows默认保留的带宽比例并不大这个调整更多是心理作用但确实有玩家反馈有效果。第四步清理临时文件。清理%TEMP%、Windows\Temp和Prefetch里的文件可以释放磁盘空间减少启动和读取时的碎片化访问。注意del命令加了/f强制删除只读文件和/q安静模式不确认但用的时候要小心别误删了正在被占用的文件。脚本里加了2nul来隐藏错误信息所以即使有文件删不掉也不会中断流程。第五步关闭GameDVR。这是Windows 10/11内置的游戏录制功能它会在后台持续录制游戏画面对GPU和磁盘都有额外开销。关了之后游戏帧数尤其是低配机器上有明显改善。需要录屏工具的话建议用OBS这类专门的软件比系统自带的好用多了。4.3 执行方式与风险控制这个脚本必须以管理员身份运行否则sc config和reg add到HKLM都会失败。具体操作是右键这个bat文件选择“以管理员身份运行”。另外脚本里的服务关闭是永久性的。如果你想恢复某个服务需要执行对应的sc config服务名start demand或start auto再net start服务名。建议在运行脚本前先备份自己的服务状态和注册表或者做一个“恢复脚本”避免优化后想改回来时手忙脚乱。还有一点清理临时文件时如果当前正跑着大型软件比如Photoshop、编译器它们的临时文件被删了会导致软件不稳定甚至报错。所以最好是重启电脑后什么程序都不开的情况下做清理这样最安全。5. 常见问题与排查技巧实录5.1 数据库方向的高频问题速查表问题现象可能原因排查思路解决方案执行SQL越来越慢索引失效、数据量增长导致执行计划变动用EXPLAIN分析执行计划检查统计信息重建统计信息、优化SQL写法、调整索引数据库死锁事务加锁顺序不一致查询死锁日志定位SQL与事务统一事务内加锁顺序、缩短事务时长连接池耗尽异常连接泄漏或最大连接数过低监控应用连接数和数据库端连接数检查代码连接释放逻辑、调大连接池上限导入数据乱码源文件字符集与数据库不匹配确认源文件编码、数据库连接字符集统一转成UTF-8或GBK后导入按show variables查字符集索引明明建了查询还是慢Where条件中函数运算导致索引失效查看SARG写法条件字段是否被函数包裹重写为无函数条件的等价SQL数据库连接超时网络不通、防火墙拦截、监听未配置先ping再telnet端口检查防火墙策略、数据库监听配置5.2 一个真实案例ALTER TABLE卡了半小时有个业务表要做加字段操作表里大概有5000万行数据。当时运维直接执行了一条ALTER TABLE结果跑了半小时还没结束DBA一看发现表被锁住了所有写操作都堵塞业务红灯。这个案例很有代表性。当时的问题是MySQL版本虽然支持Online DDL但操作期间仍然会有短暂的元数据锁等待。而表上正好有长事务一直没提交导致ALTER排队等锁。解决办法是先查information_schema.innodb_trx找到长事务和业务方确认后kill掉长事务再重新执行变更这次几分钟就完成了。这条经验告诉我们做任何表结构变更前一定要先看有没有长事务和锁等待。排查SQL可以用SELECT * FROM information_schema.innodb_trx\G SELECT * FROM sys.innodb_lock_waits\G有时候不是变更语句本身慢而是它一直在等锁释放。5.3 Windows批处理优化失败的情况有些玩家反馈这个bat脚本运行后游戏性能反而没提升甚至帧数更低。这里可能存在几个原因。一是电源模式虽然设成了高性能但笔记本厂商的电源管理软件比如联想的Lenovo Vantage、戴尔的Dell Power Manager会自动覆盖系统设置导致高性能模式不生效。解决方法是去厂商软件里调整电源方案或者用厂商高性能模式。二是关闭SysMain后在某些系统上反而会导致冷启动应用变慢虽然游戏内帧数高了但整体体验没有提升。这种情况下建议只保留SysMain开启其他步骤照旧。三是网络延迟优化。多数游戏的网络延迟瓶颈在服务端或宽带链路本地TCP注册表调整的效果非常有限。如果是Wi-Fi环境还不如换有线网络来得有效。所以别把这个脚本神化它的作用更多是“锦上添花”。5.4 关于多数据库协同的常见疑问现在很多项目不止用单一数据库比如MySQL存业务数据、ClickHouse做分析、Redis做缓存、向量数据库存知识库。这种组合架构很常见但也会引入一个常见问题数据同步。数据同步不是简单地把A库的数据COPY到B库还需要考虑格式转换、增量更新、延迟容忍度。比如MySQL到ClickHouse可以用Dolphinscheduler做周期性的数据抽取任务热搜词里就有“dolphinscheduler 数据库数据抽取”这个方向大家关注度很高。我在项目里常用的同步方案是监听MySQL的binlog用中间件把变更事件异步写入消息队列再消费消息写入ClickHouse或Elasticsearch。这个方案能实现接近实时的同步但架构复杂度也高。另一个更轻量的方案是离线定时抽取比如每天凌晨跑一次全量加增量。如何取舍取决于业务对数据新鲜度的要求有多高。6. 给同样在坚持打卡学习的人几句实话今天是第四天说实话最难的不是学习本身而是保持节奏。我的经验是每天不要贪多定一个小到不可能放弃的目标。比如今天就是理解一个概念、记住五个英文术语、写出一小段英文总结。只要完成了这三件小事就算打卡成功。这个“与AI”系列我用的AI工具主要是ChatGPT、Claude和Kimi它们各有特色。翻译和术语解释我用ChatGPT比较多长文档阅读和代码生成用Claude国产中文语料方面的问答我会顺手问问Kimi。工具不唯一关键是你得清楚自己想要什么——是练口语、读文档、学词汇还是搞懂了某个技术点。AI只是放大你的学习效率不能替代你独立思考的过程。数据库和性能优化这个主题我打算再深挖几天。后面的打卡笔记里我会继续整理SQL优化的实践案例、数据库锁机制的详细分析还有Windows游戏性能优化脚本的进阶版本。有同样想法的朋友可以在评论区聊聊你最近在学的方向和踩过的坑互相借鉴一下比一个人闷头学强得多。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →