针对优化器在某些场景下,很难准确估算表扫描行数、谓词选择率和执行计划代价的情况,PolarDB MySQL版提供了自适应执行能力,支持根据真实的数据信息自动调整执行计划。本文介绍了自适应执行能力的背景信息和使用说明等内容。
背景信息
优化器会根据统计信息和部分数据采样信息来做基数和估算选择率,这些信息可能因采样精度、采样方式等原因导致估算偏差较大。同时,还有广泛的场景没有相关的统计信息,此时数据库会根据经验值或者某种数学假设去评估统计信息,这可能会导致评估的值与实际值偏差较大。对于优化器估算与实际不符导致选错执行计划的场景,优化器难以预先收集对应的信息。
若使用PolarDB MySQL版提供的列存索引(IMCI)功能,根据IMCI的行列分流方案,当执行查询语句时,若优化器估算其在行存执行的代价估算偏低,此时可能会将某些慢查询会路由到行存执行。
针对上述路由错误的问题,之前的解决方案如下:
调低路由到列存的代价阈值,此方案容易导致大量的短查询路由到列存,从而导致列存负载太高,阻塞了其他查询。
使用计划固化 (Statement Outline)功能,将固定指定模板的查询路由到列存,如通过添加以下示例中的outline可以强制该查询语句路由到列存执行。但该方式会导致运维成本大幅增加。
CALL dbms_outln.add_optimizer_outline("<Schema_name>", "/*+ SET_VAR(cost_threshold_for_imci=0) SET_VAR(imci_ap_threshold=0) */","<query>");
PolarDB MySQL版提供的自适应执行能力可以应用于行列路由中,将错误路由到行存的慢查询自动切换到列存执行,以保证执行效率。
技术原理
通过自适应执行能力,数据库会在优化阶段将查询中各个查询块(Query block)和整体的扫描数据行数加入到监控信息中,如果查询语句在代价计算后没有选择列存,优化器会计算触发自适应执行能力的阈值。在执行阶段,当查询块(Query block)或整体的扫描数据行数触发了计算的自适应执行能力的阈值,执行器会判断是否切换到列存执行。切换到列存前,优化器会保证行存的执行结果集没有返回给客户端,并且切换到列存执行后,PolarDB会清空已缓存的行存结果集。
使用前提
集群版本需为PolarDB MySQL版8.0.1版本,且修订版本为8.0.1.1.39及以上。
使用说明
开启或关闭自适应执行能力
您可以登录PolarDB控制台。在目标集群的参数配置页面将参数loose_adaptive_plans_switch
的值设置为'imci_chosen=on'
来开启自适应执行能力。设置参数值的具体操作请参见设置集群参数和节点参数,使用自适应执行能力时涉及的具体参数见下表。
参数名称 | 级别 | 参数说明 |
loose_adaptive_plans_switch | Global/Session | 自适应执行能力控制开关。取值范围如下:
|
loose_adaptive_plans_max_time | Global/Session | 允许切换自适应执行能力的SQL语句已执行时间的最大值。即当查询语句在原计划的执行时间超过该时间后,即使触发切换计划阈值,也不再切换执行计划。 取值范围:0~1800000。默认值为500。单位为毫秒。 |
查看自适应切换执行计划的次数
您可以在数据库中执行以下SQL语句,来查看从开启自适应执行能力开始,截止到目前的自适应切换执行计划的次数。
SHOW GLOBAL STATUS LIKE 'Adaptive_plan_used';
其中,变量Adaptive_plan_used
说明如下:
变量名称 | 级别 | 变量说明 |
Adaptive_plan_used | Global | 从开启自适应执行能力开始,截止到目前的自适应切换执行计划的次数。 |