一、迁移后的性能困局1.1 为什么迁移完性能会下降我原来在SQL Server上跑得好好的怎么迁到金仓就慢了其实大多数情况下不是数据库不行是你的SQL和配置还是SQL Server那一套没跟着迁过来的数据库一起调整。为什么会有这种情况我总结了几个常见原因SQL Server有自己的SQL方言很多写法是它独有的。迁到金仓之后语法虽然能跑通但优化器不一定能高效处理。比如SQL Server里的一些表提示、连接提示到了金仓就没用了还有一些特殊的函数用法执行计划完全不一样。然后很多团队迁移的时候只迁了表结构和数据索引要么没迁全要么直接照搬SQL Server的索引策略。可不同数据库的索引机制、优化器行为是不一样的。SQL Server里好用的索引金仓里不一定好用SQL Server里能走索引的查询金仓里可能就全表扫描了。参数配置不对很多人装完金仓参数全用默认值就直接上线了。内存分配太小、并发参数太低、IO相关参数没调啥的 这些问题都要确认好迁移才没问题。或者是锁和阻塞没处理好SQL Server和金仓的锁机制、事务隔离级别都有差异。原来的事务写法在SQL Server里没问题迁到金仓可能就容易出现锁等待、阻塞。并发一高整个系统就跟堵着了都在等然后谁也跑不动。所以你看不是数据库不行是迁移工作只做了一半——数据迁过来了配置、SQL、索引这些都没搞好1.2 先定位再优化很多人一遇到性能问题上来就瞎调——改改这个参数加加那个索引改改写SQL。调对了是运气调不对的话就会越调越差。我总结了一下调优的步骤先定位再优化先SQL再系统说白了就是先定位再优化先搞清楚问题是出在哪儿是慢SQL多还是内存不够还是IO瓶颈还是锁阻塞博主发现其实80%的性能问题都是SQL和索引的问题。先把SQL优化好把索引建对大部分问题就解决了。剩下的20%再去调系统参数。先做成本低、见效快的优化比如加索引、改SQL写法这些改动小、风险低、见效快。复杂的参数调整、架构调整放在后面。这个思路来的话调优效率高风险也小。1.3 金仓的性能工具链比你想象的丰富很多人用金仓只知道一个EXPLAIN看执行计划别的啥也不知道。其实金仓自带的性能诊断工具非常丰富而且都是针对金仓内核专门优化过的特别好用。KWR金仓负载信息库相当于一个全面的性能健康体检报告告诉你数据库整体哪儿有问题KSH会话历史采样可以回溯某个时间点数据库在干什么哪个会话在等什么KDDM数据库诊断监控自动帮你分析性能问题给出优化建议还有sys_stat_statements统计视图、慢日志、锁等待视图等等。这些工具用好了我们开发运维找问题调优就简单很多问题在哪儿都能看到。可惜很多伙伴不知道或者知道但不会用。今天这篇文章博主就一边讲调优一边把这些工具的用法也给大家讲清楚。二、SQL优化篇从定位到改写一套完整的打法SQL优化是性能调优的很重要的。我做过的调优项目里80%以上的性能问题都是通过SQL优化和索引优化解决的。这一部分我就从怎么找到慢SQL开始一步步讲到怎么把慢SQL改快2.1 定位低效SQL调优的第一步永远是找到那些跑得慢的SQL。金仓里找慢SQL其实有好几个方法来找慢查询日志这是最基础是在sys_kingbase.conf这个里面开启慢日志把执行时间超过某个阈值的SQL都记录下来。log_min_duration_statement 1000 # 单位毫秒超过1秒的SQL都记录开启之后所有超过1秒的SQL都会写到日志文件里。我们就可以定期去分析慢日志就能知道哪些SQL跑得sys_stat_statements统计视图这是博主比较常用的方法比慢日志好用多了。开启这个插件之后金仓会自动统计所有SQL的执行情况执行了多少次、总耗时多少、平均耗时多少、最慢的一次是多少这些信息然后我们就可以直接查视图就能拿到数据不用去翻日志文件就比如查看总耗时最长的TOP 20 SQLSELECTquery,calls,total_time,mean_time,max_timeFROMsys_stat_statementsORDERBYtotal_timeDESCLIMIT20;这个视图的信息非常全我们可以按总耗时排、按平均耗时排、按调用次数排博主一般调优的第一件事就是把这个视图拉出来找出那些消耗总时间最多的SQL优先优化一下这些。该有人问博主了为什么优先优化总时间最多的因为一条SQL哪怕再慢如果一天只跑一次影响也有限但一条SQL每次只慢100毫秒一天跑10万次总时间就是10000秒这样的话我们就可以看出来影响的大小了。KWR报告还有一个方法KWR报告这个相比上面两个的话就比较高级了后面博主会专门讲。KWR报告会自动帮你统计TOP SQL按各种维度排序还会给你分析SQL的问题特别方便。分析执行计划找到慢SQL了接下来我们就要分析一下为什么会慢分析的工具就是执行计划EXPLAIN。很多人看执行计划就看一个有没有走索引走了索引就觉得没问题没走索引就觉得有问题。博主一般看执行计划重点看这几个东西第一看操作类型。是顺序扫描全表扫描还是索引扫描、是哈希连接还是嵌套循环或者说是排序还是用了索引排序主要是不同的操作性能差距很大嘞。全表扫描几百万行跟索引扫描几行就品吧。第二看预估行数和实际行数的差距。这个的话就比较重要了优化器是根据统计信息来估算行数的估算得准执行计划就好估算不准执行计划就会选错。如果预估行数跟实际行数差了好几倍、几十倍说明统计信息不准优化器选错了执行计划SQL自然就慢了。这时候我们要做的不是改SQL而是更新统计信息ANALYZEsys_order;第三看过滤条件的位置。过滤条件是在扫描阶段就用上了还是在后面才过滤谓词下推做得好不好直接影响中间结果的数据量。如果一个很严的过滤条件到很后面才用上中间产生了大量无用数据那性能肯定好不了。第四看连接顺序和连接方式。多表关联的时候表的关联顺序对不对用的连接方式合理不就比如小表驱动大表的话用嵌套循环如果是大表关联大表的话用哈希连接。这些基本的东西我们还是要有的。给大家举个真实的例子这次项目里有一条慢SQL查某个时间段的订单明细关联了订单表、订单明细表、商品表、客户表四张表。我看执行计划发现优化器把订单明细表当成了驱动表先全表扫了一遍再去关联其他表。为什么因为统计信息不准优化器以为订单明细表符合条件的只有几百行实际上有几十万行。执行计划选错了SQL能不慢吗更新了统计信息之后优化器重新选了执行计划先用订单表过滤出符合条件的订单再去关联明细表SQL直接从30秒跑到了1秒。你看就这么简单一个操作性能提升了30倍。很多时候不是SQL写得有多烂就是统计信息不准优化器选错了计划。2.3 第三步索引优化关于索引优化博主总结了几个比较常见的WHERE条件里的字段优先建索引这个是最基本的。经常用来过滤的字段比如订单号、用户ID、状态、时间都应该建索引。但要注意选择性高的字段建索引效果才好。比如性别这种只有两个值的字段建了索引也没用优化器不会走的。复合索引遵循最左匹配原则多个字段经常一起用在WHERE条件里就建复合索引。复合索引要注意字段顺序把选择性最高的、最常用的字段放左边。比如经常按部门状态时间查询那就建(dept_id, status, create_time)的复合索引。覆盖索引让查询不用回表什么是覆盖索引就是你要查的所有字段都在索引里不用再回表去取数据。比如你要查SELECT emp_name, emp_salary FROM sys_employee WHERE dept_id 10如果建了(dept_id, emp_name, emp_salary)的复合索引那数据库直接从索引里就能拿到所有数据不用再回表性能特别好。覆盖索引是性能提升的利器尤其是那些高频的查询能用就用。不要建太多索引索引不是越多越好。每个索引都要占存储空间而且每次插入、更新、删除数据都要维护所有索引会拖慢写入性能。一般来说一张表的索引数量控制在5个以内比较合适。不要每个字段都建索引那是懒人的做法。定期清理无用索引。系统跑久了会有很多没人用的索引白白浪费空间、拖慢写入。金仓里可以通过sys_stat_user_indexes视图看索引的使用情况SELECTrelname,indexrelname,idx_scanFROMsys_stat_user_indexesWHEREidx_scan0ORDERBYrelname;那些从来没被用过的索引该删就删没啥影响因为这个索引从来没被使用过的索引这次调优项目里光是索引优化这一项俺们团队就加了二十多个复合索引和覆盖索引删了十几个没用的索引这个项目的整体查询性能提升了很多2.4 第四步SQL改写优化索引加了统计信息也更新了SQL还是慢咋弄那可能就是SQL写法的问题了。有些SQL写法优化器很难优化就得靠人来改常见的SQL改写优化有这么几种博主给大家举例说一下改写一避免在索引列上做运算和函数。错误写法索引列上套函数索引失效SELECT*FROMsys_orderWHEREDATE(create_time)2026-08-10;正确的是这样的SELECT*FROMsys_orderWHEREcreate_time2026-08-10ANDcreate_time2026-08-11;第一种写法索引列上有函数优化器没法用索引只能全表扫第二种的话条件值是范围索引列是干净的就能走索引范围扫描。性能差几十上百倍都正常。改写二子查询改JOIN。很多人喜欢写子查询觉得逻辑清晰。但有些子查询优化器处理不好性能特别差。比如IN子查询、EXISTS子查询有时候改成JOIN性能会好很多。子查询写法SELECT*FROMsys_orderWHEREcust_idIN(SELECTcust_idFROMsys_customerWHEREcity上海);JOIN写法SELECTo.*FROMsys_order oJOINsys_customer cONo.cust_idc.cust_idWHEREc.city上海;当然了这个不是绝对的得看具体场景。改完之后看执行计划哪个好用哪个。改写三大偏移量分页改游标分页。这个我之前也讲过。LIMIT 100000, 20这种深分页越翻越慢。改成游标分页带上一页的最后一个ID直接定位性能好得多。慢的写法大偏移量SELECT*FROMsys_logORDERBYlog_idLIMIT100000,20;游标分页SELECT*FROMsys_logWHERElog_id上一页最小log_idORDERBYlog_idDESCLIMIT20;改写四避免SELECT *。这个也说过很多遍了。只查需要的字段不要查全部。一是减少数据传输二是更容易用上覆盖索引。我见过太多系统一个列表查询查了三十多个字段页面上只显示五个纯浪费SQL改写的技巧还有很多这里就不一一列举了。核心思路就是站在优化器的角度思考怎么写能让优化器更容易选出好的执行计划。2.5 第五步Hint——给优化器指路SQL改了索引加了优化器还是选错执行计划怎么办这时候就可以用Hint了。Hint是什么就是你给优化器的提示告诉它你应该这么做。金仓支持很多种Hint比如索引Hint强制走某个索引或者不走某个索引连接方式Hint强制用哈希连接、嵌套循环连接或者合并连接连接顺序Hint强制表的关联顺序并行度Hint指定查询用多少并行度。举个例子-- 强制走idx_sys_order_custid索引SELECT/* IndexScan(o idx_sys_order_custid) */*FROMsys_order oWHEREcust_id1001;再比如-- 强制用哈希连接SELECT/* HashJoin(a b) */*FROMsys_order aJOINsys_customer bONa.cust_idb.cust_id;Hint是个好东西特别适合那种优化器就是选不对计划的场景。但我要提醒一句Hint要慎用。为什么因为数据是会变的。今天这个执行计划是最优的过半年数据变了可能就不是最优的了。但Hint是写死的优化器没法自动调整了。所以Hint是最后手段能不用就不用。实在没办法了再用。2.6 第六步QueryMap——不改代码也能优化SQL这是金仓一个特别好用的功能很多人不知道。什么是QueryMap简单说就是SQL映射。你应用里发过来一条SQL金仓收到之后自动把它替换成另一条等价的、性能更好的SQL去执行。应用代码完全不用改数据库层面自动帮你改写SQL。这个功能太实用了。什么时候用应用是第三方的你改不了代码SQL写得太烂但改代码风险大、周期长紧急故障需要快速优化来不及改代码发版。举个例子应用里发过来的SQL是SELECT*FROMsys_orderWHEREDATE(create_time)2026-08-10;这条SQL因为索引列上有函数走不了索引很慢。但你又改不了应用代码怎么办用QueryMap配置一条映射规则把这条SQL自动改写成SELECT*FROMsys_orderWHEREcreate_time2026-08-10ANDcreate_time2026-08-11;应用那边完全无感知数据库自动帮你改写性能直接上去了。QueryMap支持精确匹配、模糊匹配、正则匹配等多种匹配方式非常灵活。配置也不复杂在sys_kingbase.conf里配置一下就行或者用SQL函数来管理。这次调优项目里我们就用QueryMap优化了七八条特别难搞的SQL。都是第三方应用里的烂SQL改不了代码用QueryMap一映射立马就快了。客户的运维主管说这功能简直是第三方应用的救星。三、系统调优篇内存、IO、锁一个都不能少SQL优化完了大部分性能问题就解决了。但如果系统整体还是慢那就要往深了挖——看看系统层面有没有瓶颈。内存够不够IO是不是瓶颈有没有锁阻塞这一部分我们就来讲讲系统层面的调优。3.1 内存调优让数据库吃饱了干活数据库性能好不好内存配置是关键。内存给够了很多数据都在内存里不用去读磁盘自然就快。内存不够动不动就要读磁盘IO一上来性能就掉下来了。金仓的内存相关参数有很多最核心的有这么几个第一个shared_buffers——共享缓冲区这是金仓最重要的内存参数没有之一。shared_buffers是金仓自己用的缓存用来缓存表数据、索引数据。这个值设多大合适一般来说专用数据库服务器的话设成系统总内存的25%到40%比较合适。比如服务器128G内存shared_buffers可以设成32G到48G左右。太小了缓存不够频繁读磁盘太大了系统内存不够用反而会用swap更慢。第二个work_mem——工作内存这个是排序、哈希连接、聚合这些操作用到的内存。每个查询、每个操作都可以用这么多内存。work_mem太小的话排序、哈希这些操作放不下就会写到磁盘上也就是磁盘排序、磁盘哈希性能特别差。work_mem设大一点这些操作就能在内存里完成快很多。但也不能设太大因为每个查询都可以用这么多并发高了总内存使用会爆炸。一般来说OLTP系统可以设小一点比如4MB到16MBOLAP/报表系统可以设大一点比如32MB到128MB。根据你的并发数和查询类型来调整。第三个maintenance_work_mem——维护操作内存这个是给VACUUM、CREATE INDEX、ALTER TABLE这些维护操作用的。这个值设大一点没关系因为维护操作不是经常跑而且同时跑的也不多。一般设成1GB到2GB就够用了建索引、vacuum的时候会快很多。第四个effective_cache_size——优化器估算用的缓存大小这个参数不实际分配内存是告诉优化器系统里大概有多少缓存可用包括数据库自己的缓存和操作系统的缓存。优化器估算成本的时候会用到这个值设得准不准会影响优化器选不选索引扫描。一般设成系统总内存的50%到75%左右。这些参数都在sys_kingbase.conf里配置改完之后重启数据库生效有些可以reload不用重启。这次项目里客户原来的shared_buffers只设了128MB默认值work_mem才4MB。128G内存的服务器数据库只用了128MB缓存这不扯吗我们给调成了shared_buffers40GBwork_mem32MBeffective_cache_size80GB。调完之后整体性能直接上了一个台阶磁盘IO降了一大半。为什么因为大部分数据都在内存缓存里了不用读磁盘了。3.2 IO瓶颈排查与优化内存调完了如果还是慢就得看看IO是不是瓶颈了。IO瓶颈怎么判断几个方法方法一看操作系统的IO指标用iostat、iotop这些工具看看磁盘利用率是不是经常100%IO等待是不是很高吞吐量是不是到上限了。如果磁盘天天跑满那IO就是瓶颈。方法二看数据库里的等待事件金仓里有等待事件的统计可以看数据库是不是经常在等IO。比如sys_stat_bgwriter视图看看检查点、后台写的情况还有sys_stat_database视图看看块读的情况。如果大量的时间都花在IO等待上那就是IO瓶颈。方法三KWR报告KWR报告里会有IO相关的统计读了多少块、写了多少块、物理读多少、缓存命中多少一目了然。IO瓶颈怎么优化几个思路第一加内存提升缓存命中率。这是最简单有效的方法。很多IO问题本质是内存不够缓存命中率低动不动就要读磁盘。内存加够了缓存命中率上去了IO自然就降下来了。第二优化SQL和索引减少IO量。烂SQL读大量无用数据自然IO高。SQL优化好了读的数据少了IO自然就降了。索引建好了不用全表扫了IO也会降。第三调整检查点相关参数。金仓的检查点checkpoint会把脏数据批量刷到磁盘上如果刷得太猛会造成IO尖峰。调整checkpoint相关的参数让刷盘更平滑避免IO尖峰。比如调整checkpoint_completion_target让检查点在更长的时间内完成IO更平稳。第四换更快的存储。如果上面的都做了IO还是瓶颈那就是存储本身性能不够了。机械盘换SSDSSD换NVMe存储性能上去了IO瓶颈自然就解了。这个是硬件层面的优化花钱就能解决简单粗暴但有效。3.3 锁与阻塞并发场景的堵车问题系统慢还有一个常见原因——锁和阻塞。就像马路上堵车了大家都走不了整个系统就慢下来了。这个问题在高并发的OLTP系统里特别常见。锁阻塞是怎么产生的简单说就是一个事务锁住了某行数据或者某张表另一个事务也要改这行数据就得等。等的时间长了就堆积起来了后面的事务都在等系统就慢了。常见的锁阻塞原因事务太大执行时间太长锁的时间太久更新操作没有合适的索引导致锁了很多不该锁的行不同的事务更新数据的顺序不一样导致死锁全表更新、批量删除这种大操作锁了整张表其他操作都等着。怎么排查锁阻塞金仓里排查锁问题有几个好用的视图sys_locks视图查看当前所有的锁谁持有的、什么类型的锁、锁的是哪个对象。SELECT*FROMsys_locksWHERENOTgranted;-- 正在等待的锁sys_stat_activity视图查看当前所有的会话在干什么、等什么、等了多久。SELECTpid,wait_event_type,wait_event,query,stateFROMsys_stat_activityWHEREwait_eventISNOTNULL;-- 正在等待的会话还有一个更方便的KSH工具后面会讲。KSH可以看到历史上的等待事件某个时间点谁在等什么、等了多久都能查出来。锁阻塞怎么解决找到了阻塞源解决就好办了第一优化事务让事务尽量短。事务越短锁的时间越短冲突的概率越低。别在事务里干乱七八糟的事比如调用外部接口、等用户输入这些都放到事务外面。事务里只做数据库操作做完赶紧提交。第二确保更新操作走索引。更新的时候如果WHERE条件能走索引就只会锁符合条件的那几行如果没走索引全表扫可能会锁很多行甚至锁整张表冲突概率大大增加。所以更新操作的WHERE条件一定要有合适的索引。第三统一更新顺序避免死锁。不同的事务如果更新数据的顺序不一样很容易死锁。比如事务A先更新表1再更新表2事务B先更新表2再更新表1就很容易死锁。所有事务都按统一的顺序更新就能大大减少死锁的概率。第四大操作分批做。大批量更新、删除别一条SQL干到底分批做。比如一次更新1000条提交一次歇一会儿再继续。这样锁的时间短不会长时间堵着其他操作。这次项目里锁阻塞也是个大问题。高峰期经常有几十个会话在等锁系统卡得不行。我们排查下来主要原因是几个批量更新的SQL没走索引锁了太多行。加了索引、改了分批更新之后锁等待直接降了80%系统顺畅多了。四、金仓神器篇KWR、KSH、KDDM三大诊断工具前面零零散散提到了几个金仓自带的性能工具这一部分我专门拿出来给大家详细讲讲。这三个工具——KWR、KSH、KDDM是金仓性能调优的三大利器用好了事半功倍。4.1 KWR数据库的体检报告先讲KWR全称是KingbaseES Workload Repository金仓负载信息库。你可以把它理解成数据库的全面体检报告。KWR会定期自动采集数据库的性能数据存到自己的库里。比如等待事件、SQL统计、IO统计、内存使用、表和索引的使用情况……你想看某个时间段的性能情况就生成一份KWR报告它会把那个时间段的所有性能数据汇总起来给你一份完整的分析报告。KWR报告里有什么KWR报告的内容非常丰富主要有这么几部分数据库概览数据库基本信息、报告时间段、负载情况TOP等待事件数据库主要在等什么是CPU、IO还是锁TOP SQL按总耗时、平均耗时、调用次数等维度排名的SQLIO统计物理读、逻辑读、写次数、缓存命中率内存统计缓冲区使用情况、命中率表和索引统计哪些表访问最多、哪些索引用得最多/最少锁和事务统计锁等待情况、事务提交回滚情况建议自动给出一些优化建议。一份KWR报告在手数据库的整体健康状况一目了然。哪里有问题、问题有多严重、该从哪儿入手全都清清楚楚。怎么生成KWR报告生成KWR报告很简单几个步骤确保KWR插件已经开启默认是开的调用KWR的快照函数生成两个时间点的快照调用生成报告的函数指定两个快照ID生成报告。-- 手动生成快照SELECT*FROMkwr.snapshot();-- 查看快照列表SELECTsnap_id,snap_timeFROMkwr.snapshotORDERBYsnap_id;-- 生成KWR文本报告SELECT*FROMkwr.report(开始快照ID,结束快照ID);生成的报告是文本格式的你可以直接看也可以导出来保存。我一般怎么用KWR我做调优的时候KWR是必看的。一般先看TOP等待事件知道数据库主要瓶颈在哪儿再看TOP SQL找到最耗时的那些SQL优先优化然后看看IO、内存、缓存命中率这些指标判断系统层面有没有问题。看完一份KWR报告整个数据库的性能状况心里就有数了接下来该调什么、从哪儿开始就很清晰了。说真的有KWR这么好用的工具调优效率至少提升一倍。不用你一个个视图去查、去算它都帮你整理好了。4.2 KSH穿越时空的性能监控录像第二个神器是KSH全称KingbaseES Session History会话历史。如果说KWR是体检报告那KSH就是监控录像。KSH会定期采样默认每秒一次所有活跃会话的状态存下来。比如某个会话在干什么、在执行什么SQL、在等什么事件、用了多少CPU、读了多少数据……这些采样数据会保留一段时间你可以回溯任何一个历史时间点看看当时数据库在干什么。KSH有什么用KSH最大的用处就是回溯问题。很多时候性能问题是偶发的等你发现的时候问题已经过去了现场没了。你不知道当时发生了什么也不知道是谁导致的只能瞎猜。有了KSH就不一样了你可以回到问题发生的那个时间点看看当时各个会话在干什么、谁在占CPU、谁在等锁、哪条SQL跑得慢。就像调监控录像一样一清二楚。举个例子凌晨三点数据库卡了五分钟早上起来发现的但不知道为什么。有KSH的话你直接查凌晨三点的会话历史看看那五分钟里数据库的主要等待事件是什么哪条SQL跑得最久谁阻塞了谁。分分钟定位根因。怎么用KSHKSH的用法也很简单主要是查视图-- 查看某个时间段的会话历史SELECT*FROMksh.historyWHEREsample_timeBETWEEN开始时间AND结束时间ORDERBYsample_time;你可以按时间查、按会话查、按等待事件查、按SQL查想怎么查就怎么查。还有一些更高级的用法比如生成ASH报告分析某个时间段的等待事件分布。这次调优项目里KSH帮了大忙。有一个间歇性的性能问题每天下午两点左右会卡几分钟但每次我们去看的时候都恢复了。后来用KSH一查发现每天下午两点有个定时任务跑一条特别烂的SQL把IO全占了导致其他查询都慢。找到原因就好办了优化了那条SQL问题就解决了。4.3 KDDM自动给你开药方的诊断专家第三个神器是KDDM全称KingbaseES Database Diagnostic Monitor数据库诊断监控。如果说KWR是体检报告KSH是监控录像那KDDM就是自动给你开药方的诊断医生。KDDM会自动分析数据库的性能数据识别出性能问题然后给你出诊断报告和优化建议。不用你自己去分析KWR、去查视图它自动帮你分析完了直接告诉你哪儿有问题、问题是什么、建议怎么优化。KDDM能诊断什么KDDM能诊断的问题很多比如TOP SQL问题哪些SQL跑得慢建议怎么优化加索引、改写SQL等索引问题哪些索引缺失、哪些索引没用、哪些索引效率低IO问题IO瓶颈在哪儿怎么优化内存问题内存配置合不合理要不要调整锁问题有没有严重的锁等待怎么解决参数问题哪些参数配置不合理建议改成多少。基本上你能想到的性能问题它都能给你诊断一下还会给出具体的优化建议。怎么用KDDMKDDM的使用也很简单调用它的诊断函数就行-- 生成诊断报告SELECT*FROMkddm.report(开始快照ID,结束快照ID);它会输出一份诊断报告里面有问题描述、严重程度、影响范围、优化建议、预期收益等等。特别详细照着做就行。我的使用感受说实话第一次用KDDM的时候我挺惊讶的。没想到国产数据库的自动诊断工具已经做得这么好了。很多问题它分析得比人还快、还准建议也很实在不是那种空话套话。当然了它也不是万能的特别复杂的问题还是得人来分析。但对于大部分常见的性能问题KDDM完全够用了能帮你省很多时间。尤其是新手不知道怎么分析性能问题的先用KDDM跑一遍大概就知道问题在哪儿了。4.4 三大工具配合使用效果翻倍这三个工具不是孤立的配合起来用效果最好。我的一般流程是先跑一份KDDM诊断报告看看它说有什么问题大概有个方向再看KWR报告验证一下KDDM说的对不对深入了解整体性能状况如果有偶发问题或者需要回溯的用KSH去查历史定位具体时间点的问题。三个工具一套组合拳打下来什么性能问题都藏不住。以前调优靠经验、靠瞎试现在有了这些工具就跟开了挂似的问题在哪儿一目了然。五、完整调优案例三周时间性能翻了三倍讲了这么多方法和工具最后给大家讲一个完整的调优案例就是我开头说的那个项目。看看从慢到快到底是怎么一步步调出来的。5.1 项目背景客户是一家中型企业刚做完SQL Server数据迁移迁到金仓KES V9R4C019。迁移完之后系统性能很差用户投诉不断。问题的话就是下面这些BI报表慢原来几分钟的报表现在要跑半小时高峰期系统卡页面响应慢经常出现锁等待业务操作超时CPU和IO经常跑满。客户自己的团队调了一个月越调越乱最后找到了我们。5.2 第一周诊断与SQL优化我们去的第一周主要做诊断和SQL优化。第一天我们是先跑了一份KWR报告和KDDM诊断报告看看整体情况。KDDM一跑直接列出来十几个问题按严重程度排好序了,其实后面我们就优化就好了严重TOP 5 SQL占用了70%的数据库时间急需优化严重缺失多个重要索引大量全表扫描警告shared_buffers设置过小缓存命中率低警告work_mem过小大量磁盘排序警告存在较多锁等待。看完报告我们心里就有数了问题主要还是在SQL和索引上系统参数也得调。第二天到第五天SQL和索引优化我们从TOP SQL里挑了最耗时的二十条一条一条优化。加复合索引、覆盖索引一共加了二十多个改写了十几条SQL把索引列上的函数都去掉了子查询改JOIN了几条第三方应用的SQL改不了代码用QueryMap配置了映射更新了所有大表的统计信息让优化器选对执行计划。就这样我们优化了好几天但是效果还是很明显的TOP 20 SQL的平均响应时间从原来的十几秒降到了不到一秒整体数据库时间降了一半多CPU使用率从高峰期90%降到了50%左右。第一周搞完客户就说感觉系统快多了5.3 第二周系统参数调优SQL优化完了第二周我们开始调系统参数。内存参数调整shared_buffers从128MB调到40GBwork_mem从4MB调到32MBmaintenance_work_mem从64MB调到2GBeffective_cache_size从4GB调到80GB。IO相关参数调整调整了检查点参数让刷盘更平滑调整了后台写进程的参数优化了预读参数并发和锁相关参数调整调整了连接数参数调整了锁超时参数优化了事务相关参数。调完之后重启了一次数据库缓存命中率从85%左右提升到了98%以上物理IO降了一大半磁盘利用率从高峰期80%降到了30%报表查询又快了一截原来跑半小时的报表现在五分钟就跑完了这周搞完后俺们这个系统性能又上了一个台阶。5.4 第三周锁优化与收尾第三周我们主要处理锁和阻塞的问题还有一些收尾工作。锁优化用KSH回溯了几次锁阻塞事件找到了出现这种问题的地方。之前博主记得有几个批量更新的SQL没走索引加了索引之后锁的行数减少很多。还有那种大事务拆成小事务缩短锁持有时间了解并且统一了更新顺序死锁基本消失了。像其他的优化清理了几十个无用索引写入性能也提升了一些还调整了几个表的存储参数教了一下运维他们怎么用KWR、KSH、KDDM这些工具。三周下来整体效果核心查询平均响应时间从原来的2-3秒降到了200-300毫秒快了将近10倍BI报表整体提速5-10倍大部分报表秒级返回高峰期CPU使用率从90%降到40%左右锁等待减少了90%业务操作几乎不再超时系统整体吞吐量提升了3倍以上。验收的时候客户CTO看完监控数据说了那句让我印象很深的话“跟换了个数据库似的。”5.5 调优的心得大部分性能问题都不是数据库本身的问题是使用方式的问题。SQL写得烂、索引建得不对、参数没调好这些才是性能差的主要原因。数据库本身的性能其实都不差就看你会不会用。调优是有方法论的不是靠瞎试。先定位、再优化先SQL、后系统先易后难。按照这个思路来效率高风险小。用好工具是很重要的。KWR、KSH、KDDM这些工具真的能帮你省很多时间。别再靠经验、靠瞎猜了工具都给你做好了用就是了。其实金仓的性能真的被很多人低估了。很多人觉得国产数据库性能不行那是你没调好。调好了之后性能真的不差甚至比很多国外数据库还好。关键是你得会调、得用好它的特性。这个也是要花时间了解的哪有那种不学就会的。六、总结做了这几年的从SQL Server到Oracle从MySQL到金仓的迁移和性能调优我最大的感受就是没有不好的数据库只有不会用的人。其实就是再好的数据库你乱建索引、乱写SQL、乱配参数它也快不了再普通的数据库你SQL写得好、索引建得对、参数调得合理其实也能跑得很快的。电科金仓作为国内自主研发的数据库这些年在性能优化上的进步我是有体会的因为用的比较早了解的也相对比较多一些。从优化器到执行引擎从内存管理到IO调度从诊断工具到自动化运维方方面面都在进步。尤其是KWR、KSH、KDDM这些工具做得真的很用心很懂DBA的痛点。有了这些工具调优不再是靠经验靠感觉了而是有数据支撑、有方法可循的了。