本文介绍SQL增强的实现原理和操作步骤,帮助您快速掌握其核心能力。
实现原理
背景信息
日志服务将存储与计算分离:存储层抽象为分区(Shard),负责数据存储和管理;计算层抽象为SQL,提供查询分析能力。
要提升SLS的分析性能,关键是增强存储层和计算层的能力。以下是几种常见方案及其对比。
方案一:分裂Shard
通过手动分裂Shard实现存储层能力扩展,间接提升计算吞吐量。
方案局限:
- 仅对新写入数据生效。 
- 活跃Shard持续产生租用费用(详见费用说明)。 
- 单查询受并发数/数据量限制。 
- 需人工介入分裂/合并操作。 
方案二:查询分治
将大查询拆解为多个子查询,通过二次聚合获取最终结果。
方案局限:
- 需维护二次聚合逻辑与中间结果存储(可通过定时SQL实现)。 
- 分析维度变更导致聚合逻辑重构。 
- 数据量级过大时仍存在计算瓶颈。 
方案三:SQL增强
开启SQL增强后,日志服务会根据数据规模自动扩展存储和计算资源,加速分析过程。
| 对比维度 | 方案一(分裂Shard) | 方案二(查询分治方案) | 方案三(SQL增强) | 
| 资源隔离性 | 存储资源独立,共享计算资源 | 存储资源独立,共享计算资源 | 存储资源独立,提供弹性独享资源 | 
| 扩展粒度 | 存储层扩展 | 计算层扩展 | 存储+计算层弹性伸缩 | 
| 运维成本 | 需人工干预 | 大查询拆解为多个子查询 | 全自动调度 | 
| 查询复杂度 | 原生SQL支持 | 需二次开发 | 原生SQL支持 | 
前提条件
- 已创建Standard Logstore。具体操作,请参见创建Logstore。 
- 已采集日志。具体操作,请参见数据采集。 
- 已配置索引。具体操作,请参见配置索引。 
操作步骤
日志服务支持如下两种开启SQL增强方式。
- 单次开启:仅当前Logstore下的查询和分析操作,使用SQL增强。 
- 默认开启:当前Project下的所有查询和分析操作(包括告警、仪表盘等),都使用SQL增强。 
控制台
单次开启SQL增强
- 登录日志服务控制台。 
- 在Project列表区域,单击目标Project。  
- 在页签中,单击目标Logstore。  
- 单击。  
默认开启SQL增强
- 登录日志服务控制台。 
- 在Project列表区域,单击目标Project。  
- 单击  图标。 图标。 
- 将鼠标悬浮在SQL独享版CU数上,然后单击设置。  
- 在编辑SQL独享版CU数面板中,打开是否默认开启的开关,然后单击确定。 
API
单次开启SQL增强
- 以下两个参数设置一个即可。 - 参数 - powerSql:设置为true,表示当前查询使用SQL增强。设置为false(默认值),使用SQL普通版。
- 参数 - query:例如查询分析语句为- * | select count(*) as pv,在分析语句中增加- set session parallel_sql=true;,表示使用SQL增强。查询分析语句为:- * | set session parallel_sql=true; select count(*) as pv。
 
- GetLogsV2(返回结果压缩后传输) - 查询Logstore中的日志数据 - 以下两个参数设置一个即可。 - 参数 - powerSql:设置为true,表示当前查询使用SQL增强。设置为false(默认值),使用SQL普通版。
- 参数 - query:例如查询分析语句为- * | select count(*) as pv,在分析语句中增加- set session parallel_sql=true;,表示使用SQL增强。查询分析语句为:- * | set session parallel_sql=true; select count(*) as pv。
 
默认开启SQL增强
CreateSqlInstance - 创建SQL独享实例   接口参数useAsDefault=true,为Project默认开启SQL增强。
SDK
此处以Java SDK为例。
前提条件
单次开启SQL增强
- GetLogs()方法 - 以下两个参数设置一个即可。 - 参数 - powerSql:设置为true,表示当前查询使用SQL增强。设置为false(默认值),使用SQL普通版。
- 参数 - query:例如查询分析语句为- * | select count(*) as pv,在分析语句中增加- set session parallel_sql=true;,表示使用SQL增强。查询分析语句为:- * | set session parallel_sql=true; select count(*) as pv。
 - import com.aliyun.openservices.log.Client; import com.aliyun.openservices.log.exception.LogException; import com.aliyun.openservices.log.response.GetLogsResponse; import java.util.Date; public class CreateSqlInstance { public static void main(String[] args) throws LogException { // 本示例从环境变量中获取AccessKey ID和AccessKey Secret。 String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"); String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"); // 设置日志服务的服务接入点。此处以杭州为例,其它地域请根据实际情况填写。 String host = "https://cn-beijing.log.aliyuncs.com"; // 创建日志服务Client。 Client client = new Client(host, accessId, accessKey); // 输入Project名称。 String projectName = "aliyun-project-test"; // logstore名称 String logstore = "request_log"; // 是否使用SQL增强,默认为false boolean useAsDefault = true; // SQL查询分析语句 String query = "* | select count(1)"; // 仅当 query 参数为查询语句时,该参数有效,表示请求返回的最大日志条数。最小值为 0,最大值为 100,默认值为 100。 int line = 3; // 仅当 query 参数为查询语句时,该参数有效,表示查询开始行。默认值为 0。 int offset = 0; // 用于指定返回结果是否按日志时间戳降序返回日志,精确到分钟级别。 // true:按照日志时间戳降序返回日志。 // false(默认值):按照日志时间戳升序返回日志。 boolean reverse = false; // 是否使用 SQL 增强。 // true:使用 SQL 增强。 // false(默认值):使用 SQL 普通版。 boolean powerSql = true; int from = (int) (new Date().getTime() / 1000 - 600); int to = (int) (new Date().getTime() / 1000); GetLogsResponse getLogsResponse = client.GetLogs(projectName, logstore, from, to, "", sql, line, offset, reverse, powerSql); System.out.println(getLogsResponse.getCpuSec()); } }
默认开启SQL增强
接口参数boolean useAsDefault = true,为Project默认开启SQL增强。
import com.aliyun.openservices.log.Client;
import com.aliyun.openservices.log.exception.LogException;
import com.aliyun.openservices.log.request.CreateOrUpdateSqlInstanceRequest;
public class CreateSqlInstance {
    public static void main(String[] args) throws LogException {
        // 本示例从环境变量中获取AccessKey ID和AccessKey Secret。
        String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        // 输入Project名称。
        String projectName = "aliyun-test-project";
        // 设置日志服务的服务接入点。此处以杭州为例,其它地域请根据实际情况填写。
        String host = "https://cn-beijing.log.aliyuncs.com";
        // 创建日志服务Client。
        Client client = new Client(host, accessId, accessKey);
        int cu = 100;
        boolean useAsDefault = true;
        client.createSqlInstance(new CreateOrUpdateSqlInstanceRequest(projectName, cu, useAsDefault));
    }
}常见问题
- 如何获取CPU时间? - 执行查询和分析操作后,将鼠标悬浮在分析结果上,查看CPU时间,如下图所示。  
- 使用一次SQL独享版的费用是多少? - 在不同的数据量中执行不同的查询和分析语句,会产生不同的SQL独享版费用,案例如下表所示。 - 查询和分析语句 - 数据量(行) - 平均每次的费用(元) - * | select avg(double_0) from stress_s1_mil1- 40亿 - 0.030 - * | select avg(double_0), sum(double_0), max(double_0), min(double_0), count(double_0) from stress_s1_mil1- 40亿 - 0.044 - * | select avg(double_0), sum(double_1), max(double_2), min(double_3), count(double_4) from stress_s1_mil1- 40亿 - 0.092 - * | select key_0 , avg(double_0) as pv from stress_s1_mil1 group by key_0 order by pv desc limit 1000- 40亿 - 0.080 - * | select long_0, avg(double_0) as pv from stress_s1_mil1 group by long_0 order by pv desc limit 1000- 40亿 - 0.075 - * | select long_0, long_1, avg(double_0) as pv from stress_s1_mil1 group by long_0,long_1 order by pv desc limit 1000- 3亿 - 0.073 - * | select avg(double_0) from stress_s1_mil1 where key_0='key_987'- 40亿 - 0.0005 
 > 增强SQL
 > 增强SQL