PostgreSQL 任意字段数组合 AND\OR 条件,指定返回结果条数,构造测试数据算法举例...

背景

在进行一些实际的POC测试时,需要根据业务提出的需求构造数据,比如按照任意字段数组合 AND\OR 条件,指定返回结果条数,构造测试数据。

需求

表记录数A

表字段数B

1、N个字段等值OR,命中M条记录

(两个条件无法同时满足)

2、X个字段等值AND,命中Y条记录

字段取值空间如何计算?

构造算法

1、N个字段等值OR,命中M条记录

单个字段单个VALUE的记录数 =   M/N

单个字段取值个数 =   A/(M/N)

2、X个字段等值AND,命中Y条记录

(仅适用于完全离散分布,优化器里最难估算的也是多个字段AND的选择性,所以PG 10增加了多列统计信息)

《PostgreSQL 10 黑科技 - 自定义统计信息》

X个字段的总取值空间 =   A/Y

单个字段的取值空间 =   X_/(A/Y)   (开X根)

例子

1、表记录数1000万

2、表字段数64

字段取值空间如何计算?

1、16个字段等值OR,命中1000条记录

单个字段取值个数 =   10000000/(1000/16.0) = 160000

1、建表,64字段,根据要求填入每个字段的取值范围

do language plpgsql $$  
declare  
  sql text := 'create table test1 (id int, ';  
begin  
  for i in 1..64 loop  
    sql := sql||' c'||i||' int default random()*160000,';  -- 单个字段取值空间  
  end loop;  
  sql := rtrim(sql,',');  
  sql := sql||')';  
  execute sql;  
end;  
$$;

根据前面提供的需求,写入1000万记录

insert into test1 select generate_series(1,10000000);

根据要求生成查询SQL,16个字段组合OR

do language plpgsql $$  
declare  
  sql text := 'select count(*) from test1 where ';  
begin  
  for i in 1..16 loop  
    sql := sql||' c'||i||' ='||(random()*160000)::int||' or';   -- 16个字段 or 查询   
  end loop;  
  sql := rtrim(sql,'or');  
  raise notice '%', sql;  
end;  
$$;

生成SQL

select count(*) from test1 where    
c1 =143477 or c2 =153395 or c3 =102052 or c4 =151143 or c5 =129060 or   
c6 =87519 or c7 =148787 or c8 =123117 or c9 =126622 or c10 =118215 or   
c11 =134245 or c12 =53791 or c13 =151020 or c14 =53076 or c15 =143204 or c16 =51640 ;

SQL实际返回数

 count   
-------  
   905  
(1 row)

与算法预期基本一致(1000)。

2、16个字段等值AND,命中20条记录

单个字段的取值空间 =   16_/(10000000/20) = 2.27

1、根据算法,得到取值空间,创建测试表

do language plpgsql $$  
declare  
  sql text := 'create table test2 (id int, ';  
begin  
  for i in 1..64 loop  
    sql := sql||' c'||i||' int default random()*1,';  -- 单个字段取值空间  
  end loop;  
  sql := rtrim(sql,',');  
  sql := sql||')';  
  execute sql;  
end;  
$$;

写入1000万数据

insert into test2 select generate_series(1,10000000);

生成测试SQL,16个字段,OR查询

do language plpgsql $$  
declare  
  sql text := 'select count(*) from test2 where ';  
begin  
  for i in 1..16 loop  
    sql := sql||' c'||i||' ='||(random()*1)::int||' and';  -- 16个字段 and 查询   
  end loop;  
  sql := rtrim(sql,'and');  
  raise notice '%', sql;  
end;  
$$;

生成SQL

select count(*) from test2 where  c1 =1 and c2 =0 and c3 =0 and c4 =1 and   
c5 =1 and c6 =1 and c7 =0 and c8 =1 and c9 =0 and c10 =0 and c11 =0 and   
c12 =0 and c13 =0 and c14 =0 and c15 =1 and c16 =0;

SQL实际返回数

 count   
-------  
   154  
(1 row)

与算法预期基本一致(取值范围作了取舍2.27,降到了2)。

原文地址:https://github.com/digoal/blog/blob/master/201809/20180905_03.md

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23503672/viewspace-2215704/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/23503672/viewspace-2215704/

### H2 数据库简介 H2 是一种轻量级的关系型数据库管理系统 (RDBMS),完全由 Java 编写而成,因此可以在任何支持 Java 的平台上运行。它提供了内存模式和磁盘持久化两种存储方式,并且可以通过 JDBC 接口轻松访问[^1]。 #### 主要特性 1. **多种工作模式** - 支持嵌入式模式、服务器模式以及混合模式等多种部署形式。 - 嵌入式模式下可以直接将 H2 集成到应用程序中;而服务器模式则允许远程客户端连接至数据库实例。 2. **高性能表现** - 利用了先进的算法和技术,在处理大量事务时仍能保持高效运转。 - 对于小型应用而言尤其适合因为启动速度快而且资源消耗少。 3. **丰富的功能集** - 提供标准 SQL 查询语言的支持同时还扩展了一些额外的功能比如JSON类型字段等。 - 内置了图形化的控制台(H2 Console),方便开发者调试查询语句并监控性能指标。 4. **良好的兼容性和灵活性** - 能够模拟其他主流关系型数据库的行为(如MySQL/PostgreSQL语法风格切换). - 可用于开发阶段作为临时替代正式生产环境中的大型数据库解决方案,便于快速迭代测试[^2]. 5. **易于安装配置** - 不需要复杂的设置过程即可投入使用. - 开发者只需下载对应版本jar包加入classpath即完成基本初始化步骤. --- ### 如何获取 H2 数据库? 官方推荐的方式是从其官方网站 https://www.h2database.com/html/main.html 下载最新稳定版 JAR 文件 。该文件包含了所有必要的组件来创建一个新的数据库实例或者接入现有的数据源。 另外也可以通过 Maven 或 Gradle 构建工具自动拉取依赖项: 对于Maven项目可添加如下pom.xml片段: ```xml <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.x.x</version><!-- 替换为实际所需版本号 --> <scope>test</scope> </dependency> ``` 如果是Gradle工程,则应在build.gradle里声明: ```groovy implementation 'com.h2database:h2:2.x.x'//同样需指定具体版本信息 ``` 以上方法均能够简化手动管理外部库的过程,确保每次构建都能获得一致的结果。 --- ### 实际应用场景举例 假设我们正在构建一个基于 Spring Boot 的微服务框架,其中涉及到频繁读写的业务逻辑操作表单记录。此时就可以考虑利用 H2 来搭建初期原型验证模型设计合理性而不必立即投入昂贵的企业级许可费用购买商业产品。 同时由于现代软件架构越来越强调模块解耦合度高,那么借助 H2 执行跨不同子系统间复杂报表统计任务变得可行起来——无需关心底层物理位置差异只专注于编写统一接口定义就好啦! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值