冰河技术
导读
♻学习路线
  • 面试必问系列

    • 面试必问
  • 架构与模式

    • Java极简设计模式
    • 实战高并发设计模式
  • Java核心技术

    • Java8新特性
    • IOC核心技术
    • JVM调优技术
  • 容器化核心技术

    • Dockek核心技术
  • 分布式存储

    • Mycat核心技术
  • 数据库核心技术

    • MySQL基础篇
  • 服务器核心技术

    • Nginx核心技术
  • 渗透核心技术

    • 渗透实战技术
  • 底层技术
  • 源码分析
  • 基础案例
  • 实战案例
  • 面试
  • 系统架构
  • Spring6核心技术
  • 分布式事务

    • 分布式事务系列视频
  • SpringBoot
  • SpringCloudAlibaba
  • 🔥AI大模型项目

    • 一站式AI智能平台
    • AI智能客服系统
    • AI智能问答系统
    • 实战AI大模型
  • 中间件项目

    • 手写高性能Redis组件
    • 手写高性能脱敏组件
    • 手写线程池项目
    • 手写高性能SQL引擎
    • 手写高性能Polaris网关
    • 手写高性能RPC项目
  • 高并发项目

    • 分布式IM即时通讯系统(新)
    • 分布式Seckill秒杀系统
    • 实战高并发设计模式
  • 微服务项目

    • 简易电商脚手架项目
  • 手撕源码

    • 手撕Spring6源码
🌍知识星球
  • 总览

    • 《书籍汇总》
  • 出版图书

    • 《深入理解高并发编程:核心原理与案例实战》
    • 《深入理解高并发编程:JDK核心技术》
    • 《深入高平行開發:深度原理&專案實戰》
    • 《深入理解分布式事务:原理与实战》
    • 《MySQL技术大全:开发、优化与运维实战》
    • 《海量数据处理与大数据技术实战》
  • 电子书籍

    • 《实战高并发设计模式》
    • 《深入理解高并发编程(第2版)》
    • 《深入理解高并发编程(第1版)》
    • 《从零开始手写RPC框架(基础篇)》
    • 《SpringCloud Alibaba实战》
    • 《冰河的渗透实战笔记》
    • 《MySQL核心知识手册》
    • 《Spring IOC核心技术》
  • 关于自己
  • 关于学习
  • 关于职场
B站
Github
导读
♻学习路线
  • 面试必问系列

    • 面试必问
  • 架构与模式

    • Java极简设计模式
    • 实战高并发设计模式
  • Java核心技术

    • Java8新特性
    • IOC核心技术
    • JVM调优技术
  • 容器化核心技术

    • Dockek核心技术
  • 分布式存储

    • Mycat核心技术
  • 数据库核心技术

    • MySQL基础篇
  • 服务器核心技术

    • Nginx核心技术
  • 渗透核心技术

    • 渗透实战技术
  • 底层技术
  • 源码分析
  • 基础案例
  • 实战案例
  • 面试
  • 系统架构
  • Spring6核心技术
  • 分布式事务

    • 分布式事务系列视频
  • SpringBoot
  • SpringCloudAlibaba
  • 🔥AI大模型项目

    • 一站式AI智能平台
    • AI智能客服系统
    • AI智能问答系统
    • 实战AI大模型
  • 中间件项目

    • 手写高性能Redis组件
    • 手写高性能脱敏组件
    • 手写线程池项目
    • 手写高性能SQL引擎
    • 手写高性能Polaris网关
    • 手写高性能RPC项目
  • 高并发项目

    • 分布式IM即时通讯系统(新)
    • 分布式Seckill秒杀系统
    • 实战高并发设计模式
  • 微服务项目

    • 简易电商脚手架项目
  • 手撕源码

    • 手撕Spring6源码
🌍知识星球
  • 总览

    • 《书籍汇总》
  • 出版图书

    • 《深入理解高并发编程:核心原理与案例实战》
    • 《深入理解高并发编程:JDK核心技术》
    • 《深入高平行開發:深度原理&專案實戰》
    • 《深入理解分布式事务:原理与实战》
    • 《MySQL技术大全:开发、优化与运维实战》
    • 《海量数据处理与大数据技术实战》
  • 电子书籍

    • 《实战高并发设计模式》
    • 《深入理解高并发编程(第2版)》
    • 《深入理解高并发编程(第1版)》
    • 《从零开始手写RPC框架(基础篇)》
    • 《SpringCloud Alibaba实战》
    • 《冰河的渗透实战笔记》
    • 《MySQL核心知识手册》
    • 《Spring IOC核心技术》
  • 关于自己
  • 关于学习
  • 关于职场
B站
Github
  • 专栏介绍

    • 开篇:我要手把手教你手搓一个高性能SQL引擎项目
  • 第01部分:需求设计

    • 第01节:为何要学习高性能SQL引擎项目
    • 第02节:高性能SQL引擎项目的目标与挑战
    • 第03节:高性能SQL引擎功能需求与流程梳理
  • 第02部分:总体架构设计

    • 第01节:高性能SQL引擎总体方案目标与架构设计
    • 第02节:高性能SQL引擎的通用化落地方案
  • 第03部分:通用模型设计

    • 第01节:高性能SQL引擎通用数据模板设计与实现
    • 第02节:高性能SQL引擎通用数据模型设计与实现
  • 第04部分:SQL引擎设计

    • 第01节:高性能SQL引擎SQL构建器设计与实现
    • 第02节:高性能SQL引擎驱动引擎设计与实现
  • 第05部分:SQL引擎实战

    • 第01节:基于通用模型动态生成SQL
    • 第02节:基于通用模板动态生成SQL
  • 第06部分:性能测试

    • 第01节:高性能SQL引擎基准性能测试
    • 第02节:高性能SQL引擎压力性能测试
  • 第07部分:专栏总结

    • 总结:高性能SQL引擎整体专栏总结

《高性能SQL引擎》性能测试-第01节:高性能SQL引擎基准性能测试

作者:冰河
星球:http://m6z.cn/6aeFbs
博客:https://binghe.site
文章汇总:https://binghe.site/md/all/all.html
源码获取地址:https://t.zsxq.com/0dhvFs5oR

沉淀,成长,突破,帮助他人,成就自我。

  • 本节难度:★★☆☆☆
  • 本节重点:对高性能SQL引擎进行基准性能测试,从全局视角了解高性能SQL引擎的设计和架构思想,并能够将其灵活应用到自身实际项目中。

大家好,我是冰河~~

完成高性能SQL引擎核心功能的设计与实现,并基于通用模型和通用模板分别给出10种典型的SQL场景后,接下来,就需要到高性能SQL引擎进行性能测试。

一、背景

截止到目前,我们已经设计和实现了高性能SQL引擎的核心功能,包括:梳理了高性能SQL引擎的需求和流程、制定了高性能SQL引擎的方案目标和架构设计、制定了通用化落地方案、设计和实现通用数据模板和数据模型、设计和实现SQL构建器和驱动引擎等。

在SQL引擎实战篇章,我们已经基于高性能SQL引擎的通用模型和通用模板动态生成SQL。那高性能SQL引擎的性能如何?接下来,就需要对高性能SQL引擎进行基准性能测试。

二、本节诉求

对高性能SQL引擎进行基准性能测试,从全局视角了解高性能SQL引擎的设计和架构思想,并能够将其灵活应用到自身实际项目中。

三、基准测试

通过JMH分别对高性能SQL引擎基于通用模型和通用模板动态生成SQL进行基准测试,最终给出基准测试结果。这里,我们以生成较为复杂的SQL为例,进行基准性能测试。

3.1 测试通用模型生成SQL

3.1.1 编写测试用例

(1)在项目工程的src/test/java下的io.binghe.sql.plugin.test.jmh包下创建ModelJmhTest类,在ModelJmhTest类上标注JMH基准测试注解,如下所示。

@Fork(1)
@Measurement(iterations = 5)
@Warmup(iterations = 3)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Threads(value = 5)
@State(Scope.Benchmark)
public class ModelJmhTest {
}

上述注解总体上表示在使用JMH进行基准测试时,同时开启5个线程,在线程共享实例的模式下预热3次、执行5次,并且输出每种方法调用的平均响应时间。

(2)在ModelJmhTest类中定义一个成员变量sqlParams,用于接收初始化时生成的sqlParams对象。并且在ModelJmhTest类中创建一个标注有JMH的@Setup注解的setup()方法,用于创建sqlParams对象,如下所示。

private SqlParams sqlParams;

@Setup
public void setUp(){
	//SQL数据表
	Table table = Table.builder().tableName("user_analysis").alias("user_analysis").build();

	// 表1聚合条件
	Aggregation agg1Table1 = Aggregation.builder().field("register_count").alias("register_count")
			.aggregationMode(AggregationEnum.SUM.getName()).build();
	Aggregation agg1Table2 = Aggregation.builder().field("login_count").alias("login_count")
			.aggregationMode(AggregationEnum.SUM.getName()).build();

	// 表1查询条件
	Condition condition1 = Condition.builder().aboveConditions(Constants.AND).field("analysis_date")
			.middleConditions(Constants.GE).fieldValue("2000-01-01").build();

	// 表1关联条件
	Join join1 = Join.builder().table(table).aggregation(Arrays.asList(agg1Table1, agg1Table2))
			.condition(Arrays.asList(condition1)).fields(Arrays.asList("analysis_date", "analysis_type", "platform_id"))
			.groupBy(Arrays.asList("analysis_date", "analysis_type", "platform_id"))
			.joinType(JoinEnum.QUERY_SUBSYSTEM.toString()).build();

	// 表2
	Table table2 = Table.builder().tableName("pay_analysis").alias("pay_analysis").build();
	// 表2聚合条件
	Aggregation agg2Table1 = Aggregation.builder().field("pay_count").alias("pay_count")
			.aggregationMode(AggregationEnum.SUM.getName()).build();
	Aggregation agg2Table2 = Aggregation.builder().field("change_count").alias("change_count")
			.aggregationMode(AggregationEnum.SUM.getName()).build();

	// 表2查询条件
	Condition condition2 = Condition.builder().aboveConditions(Constants.AND).field("analysis_date")
			.middleConditions(Constants.GE).fieldValue("2000-01-01").build();

	// 连接表条件
	Condition joinCondition1 = Condition.builder().aboveConditions(Constants.AND).field("user_analysis.analysis_date")
			.middleConditions(Constants.EQ).fieldValue("pay_analysis.analysis_date").build();
	Condition joinCondition2 = Condition.builder().aboveConditions(Constants.AND).field("user_analysis.analysis_type")
			.middleConditions(Constants.EQ).fieldValue("pay_analysis.analysis_type").build();
	Condition joinCondition3 = Condition.builder().aboveConditions(Constants.AND).field("user_analysis.platform_id")
			.middleConditions(Constants.EQ).fieldValue("pay_analysis.platform_id").build();

	// 表2关联条件
	Join join2 = Join.builder().table(table2).aggregation(Arrays.asList(agg2Table1, agg2Table2))
			.condition(Arrays.asList(condition2)).fields(Arrays.asList("analysis_date", "analysis_type", "platform_id"))
			.groupBy(Arrays.asList("analysis_date", "analysis_type", "platform_id")).joinType(JoinEnum.LEFT.toString())
			.joinCondition(Arrays.asList(joinCondition1, joinCondition2, joinCondition3)).build();

	Aggregation agg1 = Aggregation.builder().field("register_count").alias("registerCount")
			.aggregationMode(AggregationEnum.SUM.getName()).build();
	Aggregation agg2 = Aggregation.builder().field("login_count").alias("loginCount")
			.aggregationMode(AggregationEnum.SUM.getName()).build();
	Aggregation agg3 = Aggregation.builder().field("pay_count").alias("payCount")
			.aggregationMode(AggregationEnum.SUM.getName()).build();
	Aggregation agg4 = Aggregation.builder().field("change_count").alias("changeCount")
			.aggregationMode(AggregationEnum.SUM.getName()).build();


	// 构造通用模型
	this.sqlParams = SqlParams.builder().table(table)
			.aggregation(Arrays.asList(agg1, agg2, agg3, agg4))
			.joins(Arrays.asList(join1, join2))
			.groupBy(Arrays.asList(
					"user_analysis.analysis_date",
					"user_analysis.analysis_type",
					"user_analysis.platform_id",
					"pay_analysis.analysis_date",
					"pay_analysis.analysis_type",
					"pay_analysis.platform_id")).build();
}

(3)在ModelJmhTest类中创建executeSql()方法,标注JMH中的@Benchmark注解,说明这个方法是主要的基准测试方法,如下所示。

@Benchmark
public void executeSql(){
	SqlEngine.getSql(sqlParams);
}

(4)创建main()方法,执行JMH的基准测试,代码如下。

public static void main(String[] args) throws RunnerException {
	final Options options = new OptionsBuilder().include(ModelJmhTest.class.getSimpleName()).build();
	new Runner(options).run();
}

ModelJmhTest类的完整代码如下所示。

@Fork(1)
@Measurement(iterations = 5)
@Warmup(iterations = 3)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Threads(value = 5)
@State(Scope.Benchmark)
public class ModelJmhTest {

    private SqlParams sqlParams;

    @Setup
    public void setUp(){
        //SQL数据表
        Table table = Table.builder().tableName("user_analysis").alias("user_analysis").build();

        // 表1聚合条件
        Aggregation agg1Table1 = Aggregation.builder().field("register_count").alias("register_count")
                .aggregationMode(AggregationEnum.SUM.getName()).build();
        Aggregation agg1Table2 = Aggregation.builder().field("login_count").alias("login_count")
                .aggregationMode(AggregationEnum.SUM.getName()).build();

        // 表1查询条件
        Condition condition1 = Condition.builder().aboveConditions(Constants.AND).field("analysis_date")
                .middleConditions(Constants.GE).fieldValue("2000-01-01").build();

        // 表1关联条件
        Join join1 = Join.builder().table(table).aggregation(Arrays.asList(agg1Table1, agg1Table2))
                .condition(Arrays.asList(condition1)).fields(Arrays.asList("analysis_date", "analysis_type", "platform_id"))
                .groupBy(Arrays.asList("analysis_date", "analysis_type", "platform_id"))
                .joinType(JoinEnum.QUERY_SUBSYSTEM.toString()).build();

        // 表2
        Table table2 = Table.builder().tableName("pay_analysis").alias("pay_analysis").build();
        // 表2聚合条件
        Aggregation agg2Table1 = Aggregation.builder().field("pay_count").alias("pay_count")
                .aggregationMode(AggregationEnum.SUM.getName()).build();
        Aggregation agg2Table2 = Aggregation.builder().field("change_count").alias("change_count")
                .aggregationMode(AggregationEnum.SUM.getName()).build();

        // 表2查询条件
        Condition condition2 = Condition.builder().aboveConditions(Constants.AND).field("analysis_date")
                .middleConditions(Constants.GE).fieldValue("2000-01-01").build();

        // 连接表条件
        Condition joinCondition1 = Condition.builder().aboveConditions(Constants.AND).field("user_analysis.analysis_date")
                .middleConditions(Constants.EQ).fieldValue("pay_analysis.analysis_date").build();
        Condition joinCondition2 = Condition.builder().aboveConditions(Constants.AND).field("user_analysis.analysis_type")
                .middleConditions(Constants.EQ).fieldValue("pay_analysis.analysis_type").build();
        Condition joinCondition3 = Condition.builder().aboveConditions(Constants.AND).field("user_analysis.platform_id")
                .middleConditions(Constants.EQ).fieldValue("pay_analysis.platform_id").build();

        // 表2关联条件
        Join join2 = Join.builder().table(table2).aggregation(Arrays.asList(agg2Table1, agg2Table2))
                .condition(Arrays.asList(condition2)).fields(Arrays.asList("analysis_date", "analysis_type", "platform_id"))
                .groupBy(Arrays.asList("analysis_date", "analysis_type", "platform_id")).joinType(JoinEnum.LEFT.toString())
                .joinCondition(Arrays.asList(joinCondition1, joinCondition2, joinCondition3)).build();

        Aggregation agg1 = Aggregation.builder().field("register_count").alias("registerCount")
                .aggregationMode(AggregationEnum.SUM.getName()).build();
        Aggregation agg2 = Aggregation.builder().field("login_count").alias("loginCount")
                .aggregationMode(AggregationEnum.SUM.getName()).build();
        Aggregation agg3 = Aggregation.builder().field("pay_count").alias("payCount")
                .aggregationMode(AggregationEnum.SUM.getName()).build();
        Aggregation agg4 = Aggregation.builder().field("change_count").alias("changeCount")
                .aggregationMode(AggregationEnum.SUM.getName()).build();


        // 构造通用模型
        this.sqlParams = SqlParams.builder().table(table)
                .aggregation(Arrays.asList(agg1, agg2, agg3, agg4))
                .joins(Arrays.asList(join1, join2))
                .groupBy(Arrays.asList(
                        "user_analysis.analysis_date",
                        "user_analysis.analysis_type",
                        "user_analysis.platform_id",
                        "pay_analysis.analysis_date",
                        "pay_analysis.analysis_type",
                        "pay_analysis.platform_id")).build();
    }

    @Benchmark
    public void executeSql(){
        SqlEngine.getSql(sqlParams);
    }

    public static void main(String[] args) throws RunnerException {
        final Options options = new OptionsBuilder().include(ModelJmhTest.class.getSimpleName()).build();
        new Runner(options).run();
    }
}

上述测试用例生成的SQL语句如下所示。

SELECT
	user_analysis.analysis_date,
	user_analysis.analysis_type,
	user_analysis.platform_id,
	pay_analysis.analysis_date,
	pay_analysis.analysis_type,
	pay_analysis.platform_id,
	sum( register_count ) AS registerCount,
	sum( login_count ) AS loginCount,
	sum( pay_count ) AS payCount,
	sum( change_count ) AS changeCount 
FROM
	(
	SELECT
		analysis_date,
		analysis_type,
		platform_id,
		sum( register_count ) AS register_count,
		sum( login_count ) AS login_count 
	FROM
		user_analysis AS user_analysis 
	WHERE
		analysis_date >= '2000-01-01' 
	GROUP BY
		analysis_date,
		analysis_type,
		platform_id 
	) AS user_analysis
	LEFT JOIN (
	SELECT
		analysis_date,
		analysis_type,
		platform_id,
		sum( pay_count ) AS pay_count,
		sum( change_count ) AS change_count 
	FROM
		pay_analysis AS pay_analysis 
	WHERE
		analysis_date >= '2000-01-01' 
	GROUP BY
		analysis_date,
		analysis_type,
		platform_id 
	) AS pay_analysis ON user_analysis.analysis_date = pay_analysis.analysis_date 
	AND user_analysis.analysis_type = pay_analysis.analysis_type 
	AND user_analysis.platform_id = pay_analysis.platform_id 
GROUP BY
	user_analysis.analysis_date,
	user_analysis.analysis_type,
	user_analysis.platform_id,
	pay_analysis.analysis_date,
	pay_analysis.analysis_type,
	pay_analysis.platform_id

至此,基于通用模型生成SQL的基准测试用例编写完毕。

3.1.2 运行测试用例

运行ModelJmhTest类的main()方法会输出大量的基准测试信息,只需要关注最后输出结果即可,如下所示。

Benchmark                Mode  Cnt   Score   Error  Units
ModelJmhTest.executeSql  avgt    5  16.739 ± 1.261  us/op

可以看到,高性能SQL引擎在基于通用模型生成复杂SQL时,平均耗时在16.739us,误差范围在1.261us,性能还是相当高的。

注意:在不同的机器上运行上面的程序,得出的结果可能不同。

3.2 测试通用模板生成SQL

3.2.1 编写测试用例

(1)在项目工程的src/test/java下的io.binghe.sql.plugin.test.jmh包下创建TemplateJmhTest类,在TemplateJmhTest类上标注JMH基准测试注解,如下所示。

@Fork(1)
@Measurement(iterations = 5)
@Warmup(iterations = 3)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Threads(value = 5)
@State(Scope.Benchmark)
public class ModelJmhTest {
}

上述注解总体上表示在使用JMH进行基准测试时,同时开启5个线程,在线程共享实例的模式下预热3次、执行5次,并且输出每种方法调用的平均响应时间。

(2)在TemplateJmhTest类中定义一个成员变量template,用于接收初始化时读取的通用数据模板。并且在TemplateJmhTest类中创建一个标注有JMH的@Setup注解的setup()方法,用于创建读取通用数据模板,如下所示。

private String template;

@Setup
public void setUp(){
	this.template = this.getJson("join_query_sql.json");
}

其中,join_query_sql.json文件的内容如下所示。

{
  "table": {
    "tableName": "user_analysis",
    "alias": "user_analysis"
  },
  "joins": [{
    "joinType": "QUERY_SUBSYSTEM",
    "table": {
      "tableName": "user_analysis",
      "alias": "user_analysis"
    },
    "fields": ["analysis_date", "analysis_type", "platform_id"],
    "aggregation": [{
      "field": "register_count",
      "aggregationMode": "SUM",
      "alias": "register_count"
    }, {
      "field": "login_count",
      "aggregationMode": "SUM",
      "alias": "login_count"
    }],
    "condition": [{
      "field": "analysis_date",
      "aboveConditions": "and",
      "middleConditions": ">=",
      "fieldValue": "2000-01-01"
    }],
    "groupBy": ["analysis_date", "analysis_type", "platform_id"]
  }, {
    "joinType": "LEFT",
    "table": {
      "tableName": "pay_analysis",
      "alias": "pay_analysis"
    },
    "fields": ["analysis_date", "analysis_type", "platform_id"],
    "aggregation": [{
      "field": "pay_count",
      "aggregationMode": "SUM",
      "alias": "pay_count"
    }, {
      "field": "change_count",
      "aggregationMode": "SUM",
      "alias": "change_count"
    }],
    "condition": [{
      "field": "analysis_date",
      "aboveConditions": "and",
      "middleConditions": ">=",
      "fieldValue": "2000-01-01"
    }],
    "joinCondition": [{
      "field": "user_analysis.analysis_date",
      "aboveConditions": "and",
      "middleConditions": "=",
      "fieldValue": "pay_analysis.analysis_date"
    }, {
      "field": "user_analysis.analysis_type",
      "aboveConditions": "and",
      "middleConditions": "=",
      "fieldValue": "pay_analysis.analysis_type"
    }, {
      "field": "user_analysis.platform_id",
      "aboveConditions": "and",
      "middleConditions": "=",
      "fieldValue": "pay_analysis.platform_id"
    }],
    "groupBy": ["analysis_date", "analysis_type", "platform_id"]
  }],
  "fields": ["user_analysis.analysis_date", "user_analysis.analysis_type", "user_analysis.platform_id", "pay_analysis.analysis_date", "pay_analysis.analysis_type", "pay_analysis.platform_id"],
  "aggregation": [{
    "field": "register_count",
    "aggregationMode": "SUM",
    "alias": "registerCount"
  }, {
    "field": "login_count",
    "aggregationMode": "SUM",
    "alias": "loginCount"
  }, {
    "field": "pay_count",
    "aggregationMode": "SUM",
    "alias": "payCount"
  }, {
    "field": "change_count",
    "aggregationMode": "SUM",
    "alias": "changeCount"
  }],
  "groupBy": ["user_analysis.analysis_date", "user_analysis.analysis_type", "user_analysis.platform_id", "pay_analysis.analysis_date", "pay_analysis.analysis_type", "pay_analysis.platform_id"]
}

(3)在TemplateJmhTest类中创建executeSql()方法,标注JMH中的@Benchmark注解,说明这个方法是主要的基准测试方法,如下所示。

@Benchmark
public void executeSql(){
	SqlEngine.getSql(template);
}

(4)创建main()方法,执行JMH的基准测试,代码如下。

public static void main(String[] args) throws RunnerException {
	final Options options = new OptionsBuilder().include(TemplateJmhTest.class.getSimpleName()).build();
	new Runner(options).run();
}

TemplateJmhTest类的完整代码如下所示。

@Fork(1)
@Measurement(iterations = 5)
@Warmup(iterations = 3)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Threads(value = 5)
@State(Scope.Benchmark)
public class TemplateJmhTest extends BaseTest {

    private String template;

    @Setup
    public void setUp(){
        this.template = this.getJson("join_query_sql.json");
    }

    @Benchmark
    public void executeSql(){
        SqlEngine.getSql(template);
    }

    public static void main(String[] args) throws RunnerException {
        final Options options = new OptionsBuilder().include(TemplateJmhTest.class.getSimpleName()).build();
        new Runner(options).run();
    }
}

上述测试用例生成的SQL语句如下所示。

SELECT
	user_analysis.analysis_date,
	user_analysis.analysis_type,
	user_analysis.platform_id,
	pay_analysis.analysis_date,
	pay_analysis.analysis_type,
	pay_analysis.platform_id,
	sum( register_count ) AS registerCount,
	sum( login_count ) AS loginCount,
	sum( pay_count ) AS payCount,
	sum( change_count ) AS changeCount 
FROM
	(
	SELECT
		analysis_date,
		analysis_type,
		platform_id,
		sum( register_count ) AS register_count,
		sum( login_count ) AS login_count 
	FROM
		user_analysis AS user_analysis 
	WHERE
		analysis_date >= '2000-01-01' 
	GROUP BY
		analysis_date,
		analysis_type,
		platform_id 
	) AS user_analysis
	LEFT JOIN (
	SELECT
		analysis_date,
		analysis_type,
		platform_id,
		sum( pay_count ) AS pay_count,
		sum( change_count ) AS change_count 
	FROM
		pay_analysis AS pay_analysis 
	WHERE
		analysis_date >= '2000-01-01' 
	GROUP BY
		analysis_date,
		analysis_type,
		platform_id 
	) AS pay_analysis ON user_analysis.analysis_date = pay_analysis.analysis_date 
	AND user_analysis.analysis_type = pay_analysis.analysis_type 
	AND user_analysis.platform_id = pay_analysis.platform_id 
GROUP BY
	user_analysis.analysis_date,
	user_analysis.analysis_type,
	user_analysis.platform_id,
	pay_analysis.analysis_date,
	pay_analysis.analysis_type,
	pay_analysis.platform_id

至此,基于通用模型生成SQL的基准测试用例编写完毕。

3.2.2 运行测试用例

运行TemplateJmhTest类的main()方法会输出大量的基准测试信息,只需要关注最后输出结果即可,如下所示。

Benchmark                   Mode  Cnt    Score    Error  Units
TemplateJmhTest.executeSql  avgt    5  106.577 ± 12.011  us/op

可以看到,高性能SQL引擎在基于通用模型生成复杂SQL时,平均耗时在106.577us,误差范围在12.011us,性能依然很高。之所以基于通用模板生成SQL的性能比基于通用模型生成SQL的性能略低,是因为基于通用模板生成SQL时,会有一个将数据从JSON字符串反序列成对象的过程。

注意:在不同的机器上运行上面的程序,得出的结果可能不同。

四、本节总结

本节,主要对高性能SQL引擎进行了基准性能测试,测试范围包括基于通用模型生成SQL和基于通用模板生成SQL。从测试结果来看,高性能SQL引擎动态生成SQL的性能是非常高的。其中,基于通用模板生成SQL会比基于通用模型生成SQL性能略低,是因为基于通用模板生成SQL时,会有一个将数据从JSON字符串反序列成对象的过程。

最后,可以在评论区写下你学完本章节的收获,祝大家都能学有所成,我们一起搞定高性能SQL引擎。

五、写在最后

在冰河的知识星球除了已完结的高性能网关和热更的RPC视频外,还有其他众多高并发、高性能中间件与业务场景项目,像DeepSeek大模型、手写高性能熔断组件、手写通用指标上报组件、手写高性能数据库路由组件、分布式IM即时通讯系统、Sekill分布式秒杀系统、手写RPC、简易商城系统等等,这些项目的需求、方案、架构、落地等均来自互联网真实业务场景,让你真正学到互联网大厂的业务与技术落地方案,并将其有效转化为自己的知识储备。

值得一提的是:冰河自研的Polaris高性能网关比某些开源网关项目性能更高,并且冰河也正在为企业级高性能RPC框架录制视频,全程带你分析原理和手撸代码。 你还在等啥?不少小伙伴经过星球硬核技术和项目的历练,早已成功跳槽加薪,实现薪资翻倍,而你,还在原地踏步,抱怨大环境不好。抛弃焦虑和抱怨,我们一起塌下心来沉淀硬核技术和项目,让自己的薪资更上一层楼。


目前,领券加入星球就可以跟冰河一起学习《DeepSeek大模型》、《手写高性能通用熔断组件项目》、《手写高性能通用监控指标上报组件》、《手写高性能数据库路由组件项目》、《手写简易商城脚手架项目》、《手写高性能RPC项目》和《Spring6核心技术与源码解析》、《实战高并发设计模式》、《分布式Seckill秒杀系统》、《分布式IM即时通讯系统》和《手写高性能Polaris网关》,从零开始介绍原理、设计架构、手撸代码。

花很少的钱就能学这么多硬核技术、中间件项目和大厂秒杀系统与分布式IM即时通讯系统,比其他培训机构不知便宜多少倍,硬核多少倍,如果是我,我会买他个十年!

加入要趁早,后续还会随着项目和加入的人数涨价,而且只会涨,不会降,先加入的小伙伴就是赚到。

另外,还有一个限时福利,邀请一个小伙伴加入,冰河就会给一笔 分享有奖 ,有些小伙伴都邀请了50+人,早就回本了!

六、其他方式加入星球

  • 链接 :打开链接 http://m6z.cn/6aeFbs 加入星球。
  • 回复 :在公众号 冰河技术 回复 星球 领取优惠券加入星球。

特别提醒: 苹果用户进圈或续费,请加微信 hacker_binghe 扫二维码,或者去公众号 冰河技术 回复 星球 扫二维码加入星球。

**好了,今天就到这儿吧,我是冰河,我们下期见~~

在 GitHub 上编辑此页
上次更新: 2026/4/29 16:18
Contributors: binghe001
Next
第02节:高性能SQL引擎压力性能测试
阅读全文
×

扫码或搜索:冰河技术
发送:290992
即可立即永久解锁本站全部文章

星球会员
跳转链接