8.1.7. SQL优化
1. SQL优化原则
优先使用 LSQL 的索引进行过滤,统计,分组,排序,能 LSQL 来实现的尽量 LSQL 实现;
一定要写 LIMIT,返回的数据条数越少越好;
尽量尽早地过滤数据,减少每个阶段的数据量;
减少不必要的列的返回;杜绝使用select *查询!
能并行执行的,就不要单点执行,如数据倾斜的场景;
如果查询返回的列数很多,请选用行存;
尽量减少扫描的分区数;
避免数据倾斜;
常见数据倾斜产生的原因:
ORDER BY ,不写LIMIT,这样只会有一个REDUCE产生,单点瓶颈;
- JOIN的KEY里面含有NULL值或者大量的重复值导致的笛卡尔积;
- ROW NUMBER的PARTION KEY分组不均衡;
- 对SUM.COUNT来说,不存在数据倾斜问题。但对COUNT(DISTINCT ),效率较低,数据量一多,准出问题;
- GROUP BY+自定义UDAF;
2. 优先使用LSQL的过滤策略
LSQL层的作用是直接对接索引的,可以极大的提升数据检索以及统计的效率,功能简单,支持的函数并不多,目前函数仅仅内置COUNT、AVG、MAX、MIN、SUM 5个聚合函数。
3. 当需要同时使用LSQL与HIVE的特性时
当用户需要同时用到HIVE的一些函数和写法,并且又想充分利用LSQL的索引特性时,可以使用子查询的方式,例如:
SELECT ABC FROM ( --LSQL 的查询 SELECT ABC FROM QUICKSTART WHERE partition='3000W' LIMIT 100 ) T --HIVE 的 BETWEEN AND WHERE T.AGE BETWEEN 20 AND 40;
4. 当需要进行NOT IN ,IN子查询时
HIVE只支持FROM的子查询,当需要使用IN的时候可以使用JOIN代替
IN :
SELECT ID FROM A LEFT OUTER JOIN B ON A.ID=B.ID WHERE B.ID IS NOT NULL;
NOT IN :
SELECT ID FROM A LEFT OUTER JOIN B ON A.ID=B.ID WHERE B.ID IS NULL;
5. 需要多表关联查询时
需要多表关联查询时使用 WITH AS 的形式
WITH B AS ( SELECT C.ID FROM C ) SELECT A.ID FROM A LEFT JOIN B ON A.ID = B.ID WHERE B.ID IS NOT NULL;