针对单条SQL执行的性能调优

    针对SQL执行时间的性能调优是最常见的性能调优,关注的问题是某一条或某一类SQL的执行时间或者执行资源的消耗(如内存、磁盘IO等)。单条SQL的性能调优往往与该SQL的执行计划相关,因此,执行计划的分析是该调优场景的最重要的手段。一般来说,应该首先通过静态分析SQL的执行计划来找到可能的调优点。

    排除优化器自身的bug原因,为了使某些SQL的执行时间或资源消耗符合预期,一般需要用户对数据库的设置做相应的修改,常见的手段包括:

    • 修改系统配置项或系统变量

    • 对数据schema进行修改,包括创建数据分区、创建二级索引等

    • 修改用户SQL,包括对SQL做等价改写、增加hint等

    • 调整并行查询的并行度

    一条SQL从发送到数据开始执行,到返回结果给用户,会经历队列等待、plan cache查询、计划优化(如果计划缓存不命中)、计划执行、返回结果等过程。当发现SQL的响应时间增加时,第一步应该明确具体是哪部分的耗时增加,此时采用的一般手段包括SQL Trace、查询SQL Audit表、查看慢查询日志等。只有明确了具体耗时在哪里,才能有针对性的进一步分析问题的根源。

    针对单条SQL的执行计划性能调优又可以分为单表访问和多表访问两种场景。对单表访问SQL来说,需要重点关注的问题包括:

    • 访问路径

    访问路径的分析是单表查询的最重要的问题之一,对于使用主表扫描的访问路径来说,执行时间一般与需要扫描的数据量(范围)成正比。一般来说,可以使用explain extended命令,将表扫描的范围段展示出来。对于有合适索引的查询,使用索引可以大大减小数据的访问量,因此对于使用主表扫描的查询,要分析没有选中索引扫描的原因,例如是由于不存在可用的索引还是索引扫描范围过大以至于代价过高。

    • 是否存在排序或聚合操作

    排序或聚合往往都是比较耗时的操作。优化器为了尽可能的降低执行时间,在有合适索引可用时,考虑直接使用索引的顺序以避免额外的排序操作,同理,用户也可以根据经常需要排序的列,创建合适的索引,以免去不必要的排序操作。

    • 分区裁剪是否正确

    分区裁剪是分区表优化的重要手段,一般来说,只要用户提供了合适的分区条件,优化器会自动跳过无需访问的分区。

    • 调整查询的并行度提高查询的并行度可以使用更多资源的代价获取单条SQL查询的性能提升,当查询牵涉到的数据量较大,分区数目较多时,可以通过提高并行度的方式加快执行时间。

    针对多表访问的SQL,除了上述针对单表的SQL调优手段之外,还需要关注多表间的连接问题,需要分析的点包括:

    • 连接顺序

    • 连接算法

    • 跨机或并行连接的数据再分布方式

    • 查询改写

    针对吞吐量的性能调优

    针对吞吐量的性能调优主要是考虑在一定资源(CPU, IO, 网络等)情况下,能够将数据库系统处理请求量最大化,我们在新业务上线以及各种大促活动前往往需要进行吞吐量评估及吞吐量的性能调优。吞吐量性能调优可考虑以下几个方面:

    • 找到慢SQL并优化

    大量慢SQL请求会消耗大量的资源,导致整体吞吐量上不去,可按如下步骤处理:

    1. 通过OCP的TOP SQL功能或利用Plan Cache视图查询耗时为TOP N的SQL
    2. 找到具体的慢SQL后,可根据前面说的针对单条SQL进行性能调优
    • 查看SQL请求是否均匀分布在不同机器上

    在多机环境下,我们需要尽量将所有机器资源都能使用到,因此需要考虑流量是否均衡,可以通过sql_audit查看SQL请求是否均衡, 影响均衡的因素主要有:

    • ob_read_consistency如何设置
    • primary zone如何设置
    • proxy或java客户端路由策略相关设置
    • 业务热点查询分区是否均衡

    • 如果是大量分布式计划需要查看子计划的RPC请求是否在不同机器上均匀分布

    大量分布式计划时一般都设置了weak读,资源消耗主要在子计划的RPC请求上,在SQL请求均衡的情况下,通过sql_audit可查看子计划RPC请求是否均衡, 影响这些子计划请求是否均匀的主要因素有:

    • observer内部路由策略相关设置
    • 业务热点查询的分区是否均衡