每日踩坑 20220111 记一次MySQL索引优化引发的思考

上午正在给领导上线东西看效果,然后客户群里就突然开始说有查询特别慢,之前也没反映过。

可能是因为前一段时间公司优化(压缩成本)了一些数据库的配置。

同样的一个查询,某些参数不同,查询时间却翻了好几倍。

看日志是数据库链接断开了,崩溃性错误。

Fatal error encountered during command execution.

后来知道这个应该是阿里云RDS设置的30s自动断,防止慢查询影响整个库的性能。

然后我就开始查,这查询我明明写的时候速度可以的。

然后手动从本地抓了最终执行的SQL语句,但这里有个关键,我忘记加上后跟的Order语句了,我复制完到正式环境数据库一执行,发现是秒出,想想客户反应也是,有些查询不慢,有些慢的一匹。

这里其实也是漏掉了一个关键信息,查询中的时间区间,这一点我们前端提醒我了,但是我给否定了。

各种排查尝试,甚至我还看了阿里云RDS的性能监控,还看了IIS的线程,因为上面漏掉Order,使我认为问题是出在站点上,所以还花了时间排查服务器和代码更改记录。

但是各种尝试都没用,仔细想想日志中说明问题还是出在数据库,确确实实查询数据量大或者慢查询了。

然后我又抓了遍执行sql,这次是用调试工具抓的,这一抓看见Order By我就知道完了,指定是它的问题。

然后直接Mysql里看一下EXPALIN,好家伙,索引选到了Order的字段单个索引,其实是一个数据修改时间。用了1m的时间才出结果,五百万单字段索引查询用了一分钟,感觉还是有点拉跨。

这里我直接把这单个字段的索引删掉就可以了,mysql又自动选择了一个多业务字段复合的索引,自然是秒出了。

这个表目前的数据量是五百万级别,每天新增的数据量会比较稳定,大概在五万左右。30+字段,已经有十来个索引了。几乎是不敢动的状态,只能任由它凌乱下去。

索引优化有非常多的困难。通常来说对于一个线上的数据库,没办法随时调整索引,而且开发没有办法对索引的调整有所感知,调整之后会不会影响其他查询?会不会越调整越凌乱?这些都是问题。

之前刚来这公司的时候就在想究竟该怎么去优化,治理索引。

实际上在我看来,大多数时候,如果表的结构设计合理,一开始对于数据规模的估算和设计比较合理这都不会造成之后严重的性能问题。当然,这是理想主义。产品经理总会在适当的时候打破你的幻想。

我接手的代码中存在很多在查询语句中指定使用索引。这显然仅仅是一种应急的解决方法。

这种做法会带来一些问题,

一是代码的维护问题,代码中不具备对索引使用的框架级支持,这意味着维护上的问题。

二是通过硬编码的方式指定索引,这会带来各种环境的问题,因为一旦索引不存在或者配置了错误的编码。会导致直接报错。查得慢一些总是比报错强。

三是通过这种方式对一些查询使用特定索引,会导致索引数量膨胀凌乱。参与开发的人员如果较多就难以控制。而且索引加多了也会导致更新与插入速度变慢,

对于大多数业务复杂的系统来说都很难接受(譬如我们现在这个)我们现在的插入速度已经相当慢了,用户可感知的卡顿。

综上所述,这几个问题已经指出了一个理想化的方案就是框架级可以对索引进行管理。

这个框架级应该具备至少以下的能力:

  • 通过对代码中或运行时的SQL语句分析可以给出建议索引甚至自动创建索引。
  • 可以在执行sql时动态选择索引(比弱智mysql引擎更好的选择方法

事实上想到这里我已经发现了我对标的不就是数据库治理吗,之前去听2021数据库大会的时候没少听那些厂商谈论这个。

这些功能大多数的数据管理工具和阿里云RDS上都有。对于开发人员来说,最好的当然还是基于自己的代码中去实现,省时省力可定制,否则又是徒增复杂度而已。

至于我要不要实现这个东西,思考了一下复杂度和可用性之后我选择放弃。

主要是没时间(lan)。



转载请标明出处

作者:AaXuan

地址:http://www.cnblogs.com/Aaxuan

知识共享许可协议

本作品采用  知识共享署名 3.0 未本地化版本许可协议  进行许可。

原文地址:https://www.cnblogs.com/Aaxuan/p/15787830.html