
# 跨分片复杂SQL调优
本章节主要针对跨分片复杂SQL时的调优操作。
#### Group by和Order by SQL调优建议
1. 当group by 字段不是表中现有的数据列时，可以使用generated column机制（MySQL5.7版本以上支持，5.6及之前版本可新建普通字段和添加索引），创建新列并添加索引，将新创建字段作为group by条件，避免使用临时表。
2. 保持group by 和order by 字段相同，其中group by字段中包含分片键时性能最优。
3. 尽量让group by和order by过程中使用索引。
 
#### Join相关SQL调优建议
1. 建议进行join操作时，join条件优先使用分片键等值连接。
2. 用结果集小的表作为驱动表，尽量减少join的循环次数（使用left join/join时，左边是驱动表，右边是被驱动表；使用right join时，右边是驱动表，左边是被驱动表）。
3. 对于被驱动表的join字段需添加索引，不建议两张大表直接进行join，尤其是包含不带限制条件的单表，将消耗大量计算资源。
4. 不建议在显示事务中使用join语句，为保证事务内数据可见性，可能无法使用最优join执行计划。
 
#### Union SQL调优建议
1. 不建议大表间进行union（不包含union all）操作，避免去重时超出临时表限制。
2. 不建议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来放开对应限制。
#### 临时表产生主要场景
1. group by和order by字段不同。
2. 使用了distinct关键字。
3. 执行union查询。
4. 部分跨分片的子查询。
5. 在join查询中：使用了非等值连接条件、两个子查询之间的连接或开启了事务。
 
