跨分片复杂SQL调优
本章节主要针对跨分片复杂SQL时的调优操作。
Group by和Order by SQL调优建议
- 当group by 字段不是表中现有的数据列时,可以使用generated column机制(MySQL5.7版本以上支持,5.6及之前版本可新建普通字段和添加索引),创建新列并添加索引,将新创建字段作为group by条件,避免使用临时表。
- 保持group by 和order by 字段相同,其中group by字段中包含分片键时性能最优。
- 尽量让group by和order by过程中使用索引。
Join相关SQL调优建议
- 建议进行join操作时,join条件优先使用分片键等值连接。
- 用结果集小的表作为驱动表,尽量减少join的循环次数(使用left join/join时,左边是驱动表,右边是被驱动表;使用right join时,右边是驱动表,左边是被驱动表)。
- 对于被驱动表的join字段需添加索引,不建议两张大表直接进行join,尤其是包含不带限制条件的单表,将消耗大量计算资源。
- 不建议在显示事务中使用join语句,为保证事务内数据可见性,可能无法使用最优join执行计划。
Union SQL调优建议
- 不建议大表间进行union(不包含union all)操作,避免去重时超出临时表限制。
- 不建议union中使用order by 和group by。
临时表调优建议
跨数据分片在执行join、union、group by、order by等复杂SQL时,DDM可能会创建临时表暂时存储数据,对临时表大小限制默认是100万行。超出限制时,会提示“Temp table limit exceeded”错误,说明当前执行SQL需要在DDM节点进行二次计算,并且所需要的临时表大小已超过实例设置。对于以上情况如遇到临时表相关报错,可评估SQL是否存在优化空间,如设置广播表、增加分批查询条件或根据分库分表架构自身特点调整SQL写法。如果无优化空间,同时评估数据量大小总体可控(参与实际计算的数据不超过300万行)、实例资源相对充裕,可酌情在控制台调整实例级参数temp_table_size_limit来放开对应限制。
临时表产生主要场景
- group by和order by字段不同。
- 使用了distinct关键字。
- 执行union查询。
- 部分跨分片的子查询。
- 在join查询中:使用了非等值连接条件、两个子查询之间的连接或开启了事务。