诊断Java代码中常见的数据库性能热点问题(4)

发表于:2016-05-04来源:infoq作者:Andreas Grabner and点击数: 标签:数据库
确保你适当地调整了连接池的大小,不要使用与你期待的负载情况不符的默认设置 出现这一问题的根本原因不在于访问量的峰值。在本文开头部分所介绍

  确保你适当地调整了连接池的大小,不要使用与你期待的负载情况不符的默认设置

  出现这一问题的根本原因不在于访问量的峰值。在本文开头部分所介绍的“系统负载 / 响应时间 / 数据库执行次数”这个仪表板中显示,应用并没有产生特别的访问量峰值情况。最终发现,在每天下午2点多这个时间段设定了一个运行报表的计划,它需要执行多个运行时间相当长的 UPDATE语句,每个语句都使用了不同的连接。这会在几分钟内阻塞其他连接,导致了应用程序在“正常的”访问量下出现性能问题,因为用户的请求无法获得数据库的连接:

  (点击放大图像)

  个别的SQL执行阻塞了其他连接达几分钟,造成了连接池资源消耗殆尽的问题

  如果你已经了解到某些请求会使连接挂起一段较长的时间,你可以选择以下几种方案:

  将这些请求发送至独立的服务器上,避免影响其他使用者

  重新设定其执行时间,只在不会影响到其他人的时间段才执行

  增加连接池大小,确保在正常的访问量下有足够的连接可用

  不过,首先你要确保对这些查询进行优化。通过分析SQL查询执行计划,以找出哪些操作是最耗时的。如今,大多数APM工具都能够让你以某种方式获取某个SQL语句的执行计划。如果没有可用的工具,最简单的方式就是使用数据库的命令行工具,或者咨询某个DBA,让他帮助你生成执行计划。

  (点击放大图像)

  通过学习SQL查询执行计划,对你的SQL语句进行优化、

  执行计划能够显示出DB引擎处理SQL语句的方式。造成SQL语句执行缓慢的原因多种多样,不仅仅限于缺少索引或是使用索引的方式不对,很多情况下是因为设计、结构或连接查询所造成的。如果你并非SQL方面的专家,可以向DBA或SQL大牛求助。

  负载测试以及在生产环境中进行监控的提示与技巧

  除了对各个请求进行分析,以指出这些问题模式之外,我同样也会关注当某个应用程序在负载情况下的长期趋势。除了我在本文开头为你展示的仪表板之外,我也会指出数据驱动行为的变化,并对数据缓存是否正确运行进行验证。

  检查点1:由于数据缓存的存在,对DB的访问次数应当逐渐减少

  下面这张图表展示了SQL语句执行的平均次数(绿色)以及SQL语句执行的总次数(蓝色)。我们为应用进行了一次两小时的性能测试,保持负载始终处于较高水平。我所期望的结果是平均次数逐渐减少,而总次数则趋向平稳。因为按照我的假设,从DB所获取的数据大多数是静态的,或是会被缓存在某个不同的层。

  (点击放大图像)

  如果你的应用表现不符合这一预期,那么可能是遇到了数据驱动的性能问题,或是产生了缓存问题

  假设如我之前所展示的一样,你的应用中产生了常见的N+1次查询问题。那么随着终端用户在DB中产生越来越多的数据,应用程序所产生的SQL平均次数也将不断提高,因为这些查询所返回的数据也会越来越多!因此,请务必注意这些数字!

  检查点2:按类别指出SQL访问模式

  示例4表现了某个后台报表应用在每天下午2点执行所造成的问题,与之类似,我同样也会关注SQL访问随着时间变化的模式。我所关注的不仅包括总执行时间,同时也包括SELECT、INSERT、UPDATE与DELETE的执行次数。这样一来,我就能够指出是否在某个时间段内会进行一些特别的活动,例如通过后台作业对大批数据进行更新。

  (点击放大图像)

  通过观察总执行时间,以及SELECT、INSERT、UPDATE与DELETE的执行次数,了解应用的数据库访问行为

原文转自:http://www.infoq.com/cn/articles/Diagnosing-Common-Java-Database-Performance-Hotspots