1.尽量不用游标
游标的操作类似将每行的值取出来,做一系列处理。如果可以去掉游标,改成一条包含多个相关子查询的SQL,性能将大大提升。
2.尽量使用VARCHAR不用CHAR
CHAR的空格可能影响性能;
CHAR和VARCHAR的关联会导致关联不正确。
3.尽量使用UNION ALL尽量不用UNION
由于UNION操作需要进行一次去重,去重对于性能影响很大,尽量保证相同数据只入库一次,不同表间无重复数据,进行UNION ALL性能会很大提升。
4.避免超大结果集的直接返回
对于查询结果集达到1万以上,尤其是百万、千万的结果集,应避免结果集的直接返回,将原始select修改为insert select,即将查询结果插入到一个结果表中或者在客户端输出时要加-q参数。
5.高精度DECIMAL可能使性能变慢
如果系统升级前使用的是低精度decimal,则升级后的高精度decimal可能使得性能变慢,这是由于高精度decimal的关联,取值等操作均要耗费更多的资源,但是这种性能变慢是正常的,只要在一个合理可接受的范围内,就不需要考虑这个问题。
6.INSERT INTO ... SELECT ... GROUP BY串行
现象:INSERT INTO ... SELECT ... GROUP BY ...并行按HASH 划分,并且是多趟聚集,导致INSERT 部分串行执行。
原因:按HASH划分数据,一趟执行不完的时候,GROUP BY操作占着线程,导致线程池中没有空闲线程,做INSERT时只能串行操作。
解决办法:
如果机器核数较多(>=32),可以将并行度调低到核数的一半,线程池使用缺省值(核数)即可;
如果核数<32,可以将并行度调大到核数的2倍。
7.hash分布列注意事项
Hash列字段在使用过程中禁止加类似LTRIM等函数处理操作,这样做会破坏hash分布,必须去掉,由外部保证字段数据的正确性。
例如:字段col1在GROUP BY、INSERT INTO SELECT 投影列中对col1加的RTRIM、LTRIM破坏了hash分布,必须去掉。
GROUP BY语句如果含有hash列,将hash列放在最前面。
多个JOIN列如果有hash列JOIN的,将hash列JOIN放到最前面。
8.scan不支持并行的场景
首先,当涉及的数据行数<=参数gbase_parallel_threshold时,不支持并行。
scan 的数据必须超过一个DC才能走并行,因为scan是按DC进行切分的。
这里需要解释一下,并不是非得select count()超过65536,而是多于一个DC即可,如:两个DC,各删除65535条,select count() 的值为2,但是实际上还是两个DC,因此可以走并行。
分级查询伪列level不支持并行。
如:
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(i INT);
INSERT INTO t1 VALUES(0),(1),(2);
SELECT i,level FROM t1 START WITH i = 0 CONNECT BY prior i+1 = i;
SELECT i,level FROM t1 START WITH i = 0 CONNECT BY prior i+1 = i GROUP BY i,level HAVING LEVEl > 0;
某些函数不支持:
RAND函数不带参数或参数为常量不支持并行
SELECT ... FROM t1 WHERE RAND() > 0;
SELECT ... FROM t1 WHERE RAND(100) > 0;
REGEXP(参数存在字段不支持,全常量支持)
SELECT ... FROM t1 WHERE a REGEXP b;
:= 操作(参数存在字段不支持,全常量支持)
SELECT ... FROM t1 WHERE @cnt := i > 0;
用SQL创建的自定义函数不支持并行,UDF支持:
如:
CREATE FUNCTION f() RETURNS INT
BEGIN
...
END
这种不支持。
全文索引不支持并行。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。