博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PostgreSQL 任意字段数组合 AND\OR 条件,指定返回结果条数,构造测试数据算法举例 ...
阅读量:5839 次
发布时间:2019-06-18

本文共 2447 字,大约阅读时间需要 8 分钟。

标签

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增加了多列统计信息)

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)。

扩展问题

转载地址:http://wuncx.baihongyu.com/

你可能感兴趣的文章
有关文件下载的文件名
查看>>
史上最详细的wamp配置虚拟域名步骤
查看>>
oracle 授权
查看>>
lv扩展磁盘空间
查看>>
java8之stream流的基本操作
查看>>
二维数组计算协方差java
查看>>
SpringBoot下Redis相关配置是如何被初始化的
查看>>
为你的AliOS Things应用增加自定义cli命令
查看>>
MongoDB 创建基础索引、组合索引、唯一索引以及优化
查看>>
百度PaddlePaddle常规赛NLP赛道火热开启
查看>>
稳了!这才是cookie,session与token的真正区别
查看>>
OSChina 周二乱弹 —— 假期余额已不足!
查看>>
前端那些事之React篇--helloword
查看>>
ios的google解析XML框架GDataXML的配置及使用
查看>>
netty-当一个客户端连接到来的时候发生了什么
查看>>
PHP_5.3.20 源码编译安装PHP-FPM
查看>>
在51CTO三年年+了,你也来晒晒
查看>>
js控制图片等比例缩放
查看>>
Java高级开发工程师面试考纲
查看>>
FreeMarker表达式
查看>>