性能调优

本文介绍AnalyticDB for MySQL中性能调优的常见问题及解决方法。

说明

当常见问题场景中未明确产品系列时,表明该问题仅适用于AnalyticDB for MySQL数仓版

常见问题概览

为什么写入峰值下降了,但是CPU没有降下来?

AnalyticDB for MySQL会对写入的数据实时地构建索引,以加速查询。构建索引需要消耗一定的系统资源,特别是在有写入峰值导致写入量暴增时,索引构建过程更加占用资源。

在哪些场景下,AnalyticDB for MySQL的查询性能比较慢?

AnalyticDB for MySQL做为分布式系统,其优势在于利用多机并行的能力,提升海量数据的处理速度,适合大数据量的分析。在某些场景中,查询计算量不是特别大,AnalyticDB for MySQL具备分布式开销,反而查询较慢。也有某些场景下,AnalyticDB for MySQL单机版集群可以更好利用存储的索引来提升查询性能。

如何解决查询内存超限?

AnalyticDB for MySQL中查询内存限制都是为了保证整个集群的稳定性,避免某些慢SQL查询导致集群崩溃。关于慢SQL查询排查分析,请参见典型慢查询,重点关注峰值内存和扫描量。

下表汇总了查询超限的错误码及对应异常和处理办法。

ErrorCode

异常原因

处理办法

CLUSTER_OUT_OF_MEMORY(32001)

集群当时内存消耗整体比较大,为了保持系统整体的稳定性,会选择断开一个内存使用特别大的查询连接,以免影响其他查询的正常运行。

  1. 建议限制查询的并发量。具体操作,请参见查询流量控制

  2. 在诊断与优化界面排查当前阶段的慢查询中有没有峰值内存和扫描量比较高的查询,并分析查询内存高的原因。

EXCEEDED_MEMORY_LIMIT(32003)

当前查询的内存使用消耗超过内存限制。

建议结合SQL排查该Query消耗内存大的算子。

OUT_OF_PHYSICAL_MEMORY_ERROR(33015)

当前Query运行时超过内部计算内存池限制。

可以排查出现问题的阶段,有没有峰值内存和扫描量比较高的查询,并分析查询内存高的原因。

查询过程中报磁盘超出限制是什么原因,应该怎么处理?

AnalyticDB for MySQL集群为弹性模式时,查询有可能会使用batch模式,查询会把查询的中间结果写入磁盘,这时候如果中间结果集较大,就有可能触发磁盘空间超出限制的情况。

ErrorCode

异常原因

处理办法

OUT_OF_SPILL_SPACE(32007)

当前落盘大小超过磁盘的限制,磁盘没有足够空间落盘。

磁盘超出限制是因为使用BSP模型运行Batch类型查询任务,大量的数据Shuffle和算子状态落盘导致磁盘空间不足、超出使用限制。需要关注采用BSP模型运行的Batch类型查询任务的峰值内存、数据扫描量和数据Shuffle量,并且适当减少此类查询的并发数量。如果集群规格比较大(计算节点多于32台),可以将batch_hash_partition_count(默认为32)参数值修改为大于等于计算节点数。例如,集群有64台计算节点,则可以将参数值调整为64,这样可以将数据分布到更多计算节点,减少磁盘超出限制的可能。若仍无法解决,请联系阿里云技术支持。

EXCEEDED_SPILL_LIMIT(32006)

如何定位查询突然变慢的原因?

同一个SQL Pattern的查询变慢,可能有如下原因:

  • 相同条件下某些表的数据量增加导致处理的数据量增加,最终导致查询变慢。

  • 查询条件有变化,例如扫描的二级分区数增多,或者查询范围增加。

  • 系统压力增加。可能是写入量增加占用了较多系统资源,影响了查询性能,也可能是有Bad SQL的存在占用了较多系统资源。

您可以单击目标SQL Pattern操作列的查看详情查看不同的SQL Pattern在正常情况下的资源消耗,例如执行次数、查询耗时、执行耗时、扫描量以及峰值内存等指标。详细信息,请参见SQL Pattern

如何定位大内存查询和占用CPU较高的查询?

更多详情,请参见典型慢查询

ANALYZE命令为什么会被诊断为慢查询?

系统在运维时间自动发起的ANALYZE命令会低优先级执行(IO限流+CPU低优先级),因此执行缓慢,耗时很长,会被诊断为慢查询,一般不会影响业务。如果CPU负载不高,或者CPU负载高与运维时间没有明显联系,可以忽略该问题。如果CPU负载持续很高,请参考下文CPU负载过高,查询响应时间受到影响如何处理。

使用统计信息功能过程中,CPU负载过高的原因?

导致CPU负载过高的原因有如下两点:

  • 在默认的运维时间04:00-05:00,系统会对表进行全量扫描,收集每列的统计信息,在该时段CPU负载过高。

  • 大部分统计信息是增量收集的,一般资源消耗不会太高。由于统计信息功能是在集群内核版本为3.1.6及以上版本的AnalyticDB for MySQL数仓版集群才默认开启的,所以当集群内核版本从3.1.6以下版本升级到3.1.6及以上版本时,会触发一次全量数据的统计信息收集,导致集群内核版本完成升级后的一段时间内统计信息收集的工作量较大,CPU负载较高,完成收集后即可缓解。

当CPU负载过高时,需要判断查询响应时间是否受影响。如果平均查询响应时间没有明显变化,说明查询响应时间未受到影响。因为ANALYZE命令是在CPU低优先级和IO限流下缓慢执行,用户本身的查询不一定会受影响,即使监控项中显示CPU负载高,但有查询任务时,资源会优先服务查询任务。

统计信息收集任务导致CPU负载过高,查询响应时间受到影响如何处理?

当查询响应时间受到影响时,依次参考以下方案处理:

  • 调整运维时间到业务低峰期。

    set adb_config O_CBO_MAINTENANCE_WINDOW_DURATION = [04:00-05:00];
  • 如果无法评估合适的低峰期,可以适当下调系统查询IO限制,默认50 MB,调整时建议不低于16 MB。

    set adb_config CSTORE_IO_LIMIT_SYSTEM_QUERY_BPS = 52428800;
  • 将统计信息收集工作划分到指定的资源组,如低优先级资源组,来隔离负载。详情请参见自动收集统计信息

    set adb_config O_CBO_AUTONOMOUS_STATS_ACCOUNT = [user_name];
  • 上调列的过期比例,以减少收集工作量。列的过期比例默认为0.1(10%),取值范围(0,1),建议上调值不超过0.5。

    set adb_config O_CBO_STATS_EXPIRED_RATIO = 0.1;

如果以上方案均不能解决问题,可以尝试关闭统计信息自治功能(set adb_config O_CBO_AUTONOMOUS_STATS_ENABLED=false;) 。但是关闭自动收集统计信息后,可能会出现查询性能回退。后续如果需要统计信息,需要您手动维护。详情请参见手动收集统计信息

通过SELECT * FROM INFORMATION_SCHEMA.COLUMN_STATISTICS查询统计信息,为什么统计信息多天未更新?

统计信息不更新的原因有如下两点:

  • 表的统计信息未过期。

    统计信息默认过期比例是0.1(10%),即数据变化量(Update、Delete、Insert或Replace)需要超过10%才会更新。如果数据变化量不大,可以再观察一周继续正常使用即可。

  • 表和列太多且数据量大。

    默认情况下,排除增量更新,一天只有1小时的收集时间。如果表和列很多,一天内无法全部更新,可能需要经过一周才能更新一次。如果表和列较多,如超1000列,并且统计信息更新时间在一周内,统计信息多天未更新属于正常现象,继续观察使用即可。

新建的表导入数据会自动更新统计信息吗?

通过INSERT OVERWRITE批量导入方式,数据导入完成后会立即自动收集基础统计信息。通过INSERT INTOREPLACE INTO等实时导入方式导入数据,需要等到运维时间,或者Build完成后的增量收集周期时间触发增量收集任务,建议您在导入数据后手动收集一次基础统计信息。详情请参见手动收集统计信息