SQL 调优三板斧,拿好拿稳了!
Java技术栈
www.javastack.cn
关注阅读更多优质文章
前言
这么多年的风里雨里多少有些技术上的技巧可以分享给大家。还记得有个曾经抖落过一段小插曲吗,发生在网管装机那个时代。
装机对于那个年代来说,其实没有太大的悬念。但外行看着还是觉得很高深。我们拿出螺丝刀,把风扇,CPU,内存,硬盘拔下来的瞬间,大家都是觉得不可思议的。我能感觉到他们的心疼,毕竟一台PC还要7,8000的时候,被我这么折腾,还是心有余悸。
但是我们老手都知道,洗手,拆箱,插拔,只要不带电操作,安全得很。甚至只要听到BIOS(年轻人估计都不知道了吧)的三长两短声,立马可辨,是内存,还是硬盘有问题了。拆装到位,一击即中。
上面是硬件部分的维护,那到软件部分怎么样呢?网上不去,软件卡了,黑屏,蓝屏?套路与硬件故障排除一样,重插网线,重启电脑(万恶的Windows 98),卸载软件重装,最后万灵的一招,PE重装系统,Ghost 备份!
现专注于数据库开发了,碰到性能有问题,其实和硬件故障排除并没有多大区别,也有个套路。
第一板斧
跟上不了网一样,第一件事情,大家会做什么?对,就是检查网线。
SQL查询太慢,你会做什么?肯定不是去看网线了,网线一断,你的SQL直接报timeout错误了,根本不给你往下执行的机会。
SQL查询太慢,我们要做的事情当然是去检查,当前的SQL是不是在跑?还是在等CPU中央司令员给你机会去跑。数据库有自己的任务分配系统,如果你的线程级别比较低,分配系统就不给你机会去执行,那也白搭。那就只能等着了。
同学可能不知道为什么要等待,而不是发完SQL就立即执行这个概念!
举例,如果我们的数据库有分布式的应用,比如读写分离,那么在系统正在执行读写分离的时候,会有大量的任务在跑,而且级别较高,占用的服务器资源就会很多,比如高CPU,高内存,高IO.这个时候,任何的查询都会被挂起,只有等待CPU/Memory/io的分配,才能 运行。
第二板斧
平时大家都是写 CRUD 的任务多,很少有人会去看数据库的实现代码。所以很多细节不会清楚。但很多厂商为我们做好了可以瞥一眼神秘的数据库引擎实现的地方,那就是 execution plan(执行计划).
在执行计划中,我们可以看到数据到底存储在哪个硬盘位置,内核是如何读取这些硬盘位置的数据,数据加载到内存后,又经过什么算法来得到我们想要的计算结果。
第三板斧
第三板斧,有些深入细节了。运行时统计信息的采样分析。
我们从IBM的论文中,可以得到这么个启示。很多引擎的算法都得益于采集到的元数据统计信息。基于这些信息,引擎会自动选择最优的算法。
比如一张表的Country字段(存储国家信息),经过统计,只有3个国家,中国,美国,欧盟。其中包含中国的记录数占据了85%的数据,而其他两国都只有7%,8%的数据。
如果有查询需要查询包含中国相关的数据,那么采用全表/全索引扫描的方式会快很多,因为回表这部分(如果不知道回表,可以往前翻翻我的文章)的成本就被极大的节约了。一旦查询其他两国,那么使用索引搜索更快。你发现某个查询在查询包含中国相关数据时,执行计划走的是 index seek, 你就可以帮执行计划调整成 index scan 或者table scan了。(同样,如果不知道怎么调执行计划,可以翻翻我之前的文章)
结尾
总结下来,就是检查等待,分析执行计划,运行时统计信息采集。如果能从这三个方面去分段调试,肯定能找到80%的性能问题。那么,找到问题等于解决了问题吗?肯定不是的。
点击「阅读原文」获取面试题大全~