南大通用GBase 8a SQL的简要优化步骤:
1、获取长sql
Select sql_text from gclusterdb.audit_log_express where TIMESTAMPDIFF(second,start_time,end_time) >2000;

需要gclusterdb.audit_log_express表的权限,2000代表执行时间长度为2000的长SQL,可以在每个集群执行后导出。
也可按时间查询,gclusterdb.audit_log_express表结构如下:
gbase> desc audit_log_express;
+-------------+---------------+------+-----+---------+-------+
| Field       | Type          | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+-------+
| hostname    | varchar(64)   | YES  |     | NULL    |       |
| thread_id   | int(11)       | YES  |     | NULL    |       |
| taskid      | bigint(20)    | YES  |     | NULL    |       |
| start_time  | datetime      | YES  |     | NULL    |       |
| uid         | bigint(20)    | YES  |     | NULL    |       |
| user        | varchar(16)   | YES  |     | NULL    |       |
| host_ip     | varchar(32)   | YES  |     | NULL    |       |
| query_time  | time          | YES  |     | NULL    |       |
| rows        | bigint(20)    | YES  |     | NULL    |       |
| table_list  | varchar(4096) | YES  |     | NULL    |       |
| sql_text    | varchar(8192) | YES  |     | NULL    |       |
| sql_type    | varchar(16)   | YES  |     | NULL    |       |
| sql_command | varchar(32)   | YES  |     | NULL    |       |
| operators   | varchar(256)  | YES  |     | NULL    |       |
| status      | varchar(16)   | YES  |     | NULL    |       |
| conn_type   | varchar(16)   | YES  |     | NULL    |       |
+-------------+---------------+------+-----+---------+-------+

2、判断表类型
根据步骤1获取到的SQL,进行逐个优化。
1)把SQL中的所有表找出来
2)gccli登录集群通过show create table 看表类型,或通过监控工具查看表类型和分布列,初步判断是否存在随机分布表,是否hash列选取有问题的表,是否存在大数据量(超过100万)建成复制表的情况,有问题进行整改,建议把所有随机分布表都改为hash分布表。
    建Hash分布列的原则基本如下:
Ø尽量选择count(distinct)值大的列做Hash分布列,让数据均匀分布。
Ø优先考虑大表间的JOIN,尽量让大表JOIN条件的列为Hash分布列(相关子查询的相关JOIN也可以参考此原则),以使得大表间的JOIN可以直接分布式执行。
Ø其次考虑GROUP BY,尽量让GROUP BY带有Hash分布列,让分组聚合一步完成。
Ø通常是等值查询的列,并且使用的频率很高的应考虑建立为hash分布列

    注意事项:
Øhash分布键只能选择 1 个 
Øhash分布键只能选择数值和字符串类型的列 
Ø作为hash分布列的列不能进行update
Ø尽量保持hash join的等值关联列在类型定义上完全相同,如char和varchar类型进行关联,可能出现结果为空情况,原因是char型
3)gccli登录集群,根据筛选条件判断各表数据量大小,判断结果集大小是否合理,是否存在漏写筛选条件的情况。
4)如果经常关联的列不是hash列,尽可能调整一致。
3、判断是否存在笛卡尔积
步骤2完成后,需要根据join关联列和筛选条件判断每个表的关联列是否存在重复值,重复值会导致笛卡尔积,大大影响SQL性能和集群整体性能。
一般使用如下语句,判断重复值前十条即可,如果有问题,前十条也能很明显会出大量重复值数据。
select 列明,count(1) from 表名 group by 列明 order by列明 desc limit 10;
4、其它优化点
1)避免使用select * from ,尤其是子查询,需要查询哪些列就显式写明那些列
2)尽量避免where条件中对列进行函数运算再进行比较,加函数会造成智能索引失效,sql性能降低。
例如:某现场原始sql为:where substr(product_no, 2, 1) in ('3', '4', '5', '8'),智能索引失效,性能非常低;
改写为: where (product_no like '13%' or product_no like '14%' or product_no like '15%' or product_no like '18%')'
3)如果数据量小(千万级)执行时间很长,按上述步骤检查没问题,可以考虑数据分布不均衡的问题,需要查看各节点使用到的表是否有偏离
4)dblink时间长的表尽量按日期去抽取
5)如果join关联的右表使用子查询可以大量减少结果集,可以考虑使用子查询过滤后再进行join。