在DWS上面存储过程执行过程中,因为优化器执行的问题会导致SQL变慢,目前有2种优化方式。
第一种:首先优化hint, 需要首先获取程序的 analyze performance 的相关信息,使用gsql 工具,具体服务器上操作
2,打出相关信息之后,需要根据执行信息进行从最下面网上找,原则上小表先做完关联,然后在大表关联,数据量大的走hash,正常情况下优化hint 能够解决查询慢的问题,当你的临时表每次执行的时候,需要先truncate,再insert,那么会存在一个问题,DWS优化器插入数据的计算估算并不准确,比如该表有1500W数据,优化器估算的只有300条,这样就会拿300条数据去进行query_mem申请,那么300条的数据申请到的内存就很小,实际需要执行1500W数据,就会很慢,长时间执行可能会因为数据落盘,导致运行缓慢。此时就需要对已经优化后的hint进行再次优化,
比如原优化hint 为:/*+no nestloop(t3 t1 t2) leading((t1 (t3 t2))) leading((t3 t2))*/
这里面 t3表实际有1500W数据,优化器估算的只有300条,那么就需要对这个t3表设置一个大概的数据量数据
修改后为:/*+no nestloop(t3 t1 t2) leading((t1 (t3 t2))) leading((t3 t2)) rows(t3 #15000000)*/
修改后起到作用,速度提升10倍
第二种方式:
这种方式在hint优化过程中不能解决慢的问题,还有一招,就是给这个程序制定运行的内存,不由优化器决定。具体如下:
--为执行该查询锁使用的内存设置为1G,解决执行该步骤过慢的情况,在没有设置的时候这个内存是由优化器自己估算,由于估算的内存过小导致数据过多节点的分发或可能导致的落盘
-- set query_mem='1GB';
--insert into 。。。。。。 程序执行段
当这段程序执行完后,需要把query_mem还原为0,
因为query_mem='1GB' 是把操作需要的内存分配了1G单独给这个程序使用,一般这种操作不建议使用,因为操作系统的内存是有限,如果每个程序都分配固定的内存,内存有限,在并发的时候会报出内存不足的情况。
query_mem 这个参数的作用范围 是仅限制当前会话有效。
参加资料:https://support.huaweicloud.com/devg-dws/dws_04_0095.html