hubble V310版本升级内容

SQL变化

功能名称说明
CREATE INDEX ... INCLUDE (col1, col2 ...)新增索引的创建方式
CREATE TABLE ... LIKE ...新增数据的like 复制
CREATE MATERIALIZED VIEW新增物化视图的创建
CREATE TEMP VIEW新增临时视图的创建
IN查询添加了对选择运算符IN的矢量化支持
NOT VALID语法在设置外键时候添加了NOT VALID
WITH...AS...新增加了递归查询
  • 增加了CREATE INDEX .... INCLUDE (col1, col2, ...)语法
create table t (a int primary key,b int,c int,d int);

要在表t的b列上创建一个唯一的B树索引并且包括列c和d

CREATE  INDEX b_idx ON T (b) INCLUDE (c, d);
  • 建表复制数据用CREATE TABLE ... LIKE ...

当执行CREATE TABLE AS SELECT语句进行建表并且进行数据复制的时候,将会导致新创建的表中丢失主键分区和外键等约束。影响数据检索查询效率。强烈推荐先执行create table t2(like t1 INCLUDING ALL EXCLUDING CONSTRAINTS)复制表结构和约束 ,再执行insert into T2 select * from T1方式导入数据。

示例如下:

CREATE TABLE t1 (id INT PRIMARY KEY, name INT NOT NULL, INDEX(name));
CREATE TABLE t2 (LIKE t1 INCLUDING ALL EXCLUDING CONSTRAINTS);
insert into T2 select * from T1;
  • 物化视图的创建

hubble支持物化视图。物化视图是存储其基础查询结果的视图。

因为物化视图存储查询结果,它们提供比标准视图更好的性能,但代价是存储查询结果所需的额外存储空间和保证结果是最新的。

物化视图和标准视图在创建、显示、重命名和删除的语法相似。

要创建物化视图,请使用CREATE MATERIALIZED VIEW语句。

CREATE MATERIALIZED VIEW emppeo
as select empno, ename
  from emp where deptno = 10 ;

为视图创建索引

create index e_idx on emppeo(ename);
  • 临时视图的创建

要创建临时视图,请将TEMP添加到CREATE VIEW语句中。并且先设置变量SET experimental_enable_temp_tables = 'on'

先设置变量:

SET experimental_enable_temp_tables = 'on'

创建临时视图:

create temp view dname_c (dname,num)
as
select d.dname ,count(1) from 
dept d 
join emp e 
on  d.deptno=e.deptno 
group by d.dname;
  • 在设置外键时候添加了not valid

示例如下:

create table t1(a int primary key,b text,c date);

create table t2(a int primary key,b int references t1(a),c text);

需要先将外键删掉,然后重建外键约束并将其状态设置成无效

alter table t2 drop constraint t2_b_fkey;

alter table t2 add constraint t2_b_fkey foreign key (b) references t1(a) not valid;
  • 递归查询

在用于更大的查询上下文之前为可能复杂的子查询用WITH提供简写名称。这提高SQL语法的可读性。

语句为子查询的结果WITH x AS (y)创建临时表名,以便在上下文中重用。

示例如下:

with e as (select * from  emp where deptno=30)
  select e.empno,e.ename,d.loc from e left join dept as d  on e.deptno = d.deptno ;
   empno | ename  |   loc
--------+--------+----------
   7698 | BLAKE  | CHICAGO
   7499 | ALLEN  | CHICAGO
   7844 | TURNER | CHICAGO
   7521 | WARD   | CHICAGO
   7654 | MARTIN | CHICAGO
   7900 | JAMES  | CHICAGO

函数变化

函数名称变化类型描述
extract优化从...中抽取部分内容
regexp_split_to_array新增用来将字符串转换成数组
localtime新增显示时间的时分秒
current_date优化显示日期(年月日)
localtimestamp新增显示时间(年月日时分秒)
age优化计算两个日期的差值
experimental_strftime优化日期转字符串
experimental_strptime优化字符串转日期
date_trunc优化时间的截取计算
log新增计算以...为底的对数
appay_agg优化把多个值合并到一个数组中
covar_pop新增求指定两个数字列的总体协方差
difference新增比较两个值的相似性
enum_first新增返回参数指定的枚举类型的第一个值
enum_last新增返回参数指定的枚举类型的第最后一个值
bit_or新增返回两个参数的按位'或 '
num_nonnulls新增返回非空输入字符的总个数
num_nulls新增返回一个null值的总个数
regexp_split_to_table新增按某个字符拆分列数据
sind新增角度值转换为弧度制
sinh新增双曲函数中双曲正弦函数
stddev_pop新增函数用于计算表达式的总体标准差
uuid_generate_v4新增生成一个uuid
var_pop新增计算表达式的总体标准方差
var_samp新增计算表达式的总体样本方差
timeofday新增返回当前日期和时间
asind新增返回反正弦值
acosd新增返回反余弦值
every新增用于检测所有元素是否都符合指定条件
  • extract根据时间获取当前的详细时间戳
select extract(epoch from now());
   extract  
+--------------+
1665626601.62315
  • regexp_split_to_array利用正则表达式将字符串分割成数组
select regexp_split_to_array('hello world', E'\\s+') as res;
       res
-----------------
  {hello,world}
  • current_date(),展示当前年月日

展示当前时间(现在只显示年月日,无后缀)

select current_date();
         current_date         
+-----------------------------+
          2022-10-11
  • 增加localtime()

展示当前时间(时分秒)

select localtime();
    localtime        
+---------------+
     16:33:30
  • localtimestamp 显示时间(年月日时分秒)
select localtimestamp();
        localtimestamp
------------------------------
  2022-11-04 10:21:11.173667
  • 时间日期差有错误的修正

age(end: timestamptz, begin: timestamptz),计算endbegin之间的时间间隔,结果体现为前值减去后值

select age(TIMESTAMPTZ '2022-03-26 14:22:10+08:00',TIMESTAMPTZ '2020-02-26 10:10:10-05:00');
            age     
+--------------------------+
  2 years 28 days 15:12:00 
  • 日期转字符串,用函数experimental_strftime()
select experimental_strftime(b,'%Y-%m-%d %H:%M:%S') from a;
  experimental_strftime
-------------------------
  2018-12-21 10:21:24
  • 字符串转日期,用函数experimental_strptime()
SELECT experimental_strptime(a,'%Y-%m-%d %H:%M:%S') FROM b;
  experimental_strptime
--------------------------
  2018-12-21 18:21:24+08
  • date_trunc获取当月最后一天的时间戳
SELECT (date_trunc('month',now()) + INTERVAL '1 MONTH' + INTERVAL '-1 second')::timestamp;
  date
--------------------------
  2022-10-31 23:59:59.000
  • log()函数的增加

例如,以2为底的对数,参数必须有一个为浮点型

select log(2.0, 64.0);
           log
-------------------------
  6.0000000000000000000
  • ARRAY_AGG()

上一个版本返回值乱码问题的解决

create table film (id int,pname  string,fname string);
insert into film values (1,'战狼二','wujing');
insert into film values (1,'断背山','lian');
insert into film values (3,'西游记','wuchengen');;
insert into film values (3,'水浒传','shinaian');
insert into film values (2,'亮剑','liyunlong');
insert into film values (2,'五号特工组','wanglikun');
SELECT
    id,
    ARRAY_AGG (pname || ' ' || fname) actors
FROM
    film 
group by id;
 id  |                actors
-----+----------------------------------------
   1 | {战狼二 wujing,断背山 lian}
   3 | {西游记 wuchengen,水浒传 shinaian}
   2 | {亮剑 liyunlong,五号特工组 wanglikun}
  • covar_pop(col1, col2)参数说明:col1, col2,数值类型列,其他类型时返回NULL

返回值:DOUBLE类型

select  covar_pop(20,30);
  covar_pop
-------------
          0
  • DIFFERENCE,值返回0-4,值越大相似性越大

用法:

DIFFERENCE(string, string)
SELECT SOUNDEX('poor') soundex_poor, SOUNDEX('pour') soundex_pour, 
DIFFERENCE('poor', 'pour') similarity;
  soundex_poor | soundex_pour | similarity
---------------+--------------+-------------
  P600         | P600         | 4
  • enum_first
CREATE TYPE my_number AS ENUM (
    'one',
    'two',
    'three',
    'four',
    'five',
    'six',
    'seven',
    'eight',
    'nine',
    'ten'
);
select enum_first('one'::my_number);
  enum_first
--------------
  one
(1 row)
  • enum_last
select enum_last('one'::my_number);
  enum_last
--------------
  ten
(1 row)
  • bit_or
select bit_or(id) from (values(null),(1),(2)) as t(id);
  bit_or
----------
       3
  • num_nonnulls
SELECT num_nonnulls(1,null,2) AS total_nonnulls;

  total_nonnulls
------------------
               2
  • num_nulls
SELECT num_nulls('PostgreSQL','MySQL','','null',null) AS total_nulls;
total_nulls

-------------
  1
  • regexp_split_to_table
select  regexp_split_to_table('11,22,33',',');
  regexp_split_to_table
-------------------------
  11
  22
  33
  • sind
select sind(45.0);
         sind
----------------------
  0.7071067811865475
  • sinh
select sinh(90.0);
          sinh
-------------------------
  6.102016471589204e+38
  • STDDEV_POP

数据准备

CREATE TABLE Player  
( 
PlayerName VARCHAR(100) NOT NULL,
RunScored INT NOT NULL,
WicketsTaken INT NOT NULL
);


INSERT INTO Player  
(PlayerName, RunScored,  WicketsTaken )
VALUES
('KL Rahul', 52, 0 ),
('Hardik Pandya', 30, 1 ),
('Ravindra Jadeja', 18, 2 ),
('Washington Sundar', 10, 1),
('D Chahar', 11, 2 ),  
('Mitchell Starc', 0, 3);

将找到WicketsTaken列的总体标准差

SELECT  STDDEV_POP(WicketsTaken) 
as Pop_Std_Dev_Wickets   
FROM Player ;
  pop_standard_deviation
--------------------------
   16.876183086099639597
  • uuid_generate_v4
select uuid_generate_v4();
            uuid_generate_v4
----------------------------------------
  165f8c68-d670-4708-aa50-ae6fc1bb72b0
(1 row)
  • VAR_POP
CREATE TABLE Player  
( 
PlayerName VARCHAR(100) NOT NULL,
RunScored INT NOT NULL,
WicketsTaken INT NOT NULL
);


INSERT INTO Player  
(PlayerName, RunScored,  WicketsTaken )
VALUES
('KL Rahul', 52, 0 ),
('Hardik Pandya', 30, 1 ),
('Ravindra Jadeja', 18, 2 ),
('Washington Sundar', 10, 1),
('D Chahar', 11, 2 ),  
('Mitchell Starc', 0, 3);

计算RunScored列的总体标准方差

SELECT  VAR_POP(RunScored ) as Run_POPVariance  
                          FROM Player ;
     run_popvariance
-------------------------
  284.80555555555555556
  • VAR_SAMP

数据准备同上一个示例

RunScored列的样本方差。

SELECT  VAR_SAMP(RunScored ) as Run_Variance 
FROM Player ;
      run_variance
-------------------------
  341.76666666666666667
  • TIMEOFDAY

返回当前日期和时间

select timeofday();
               timeofday
----------------------------------------
  Fri Nov 4 11:33:43.240953 2022 +0800
  • asind
select asind(1);
  asind
---------
     90
(1 row)

说明1的反正弦正好是90°

  • acosd
select acosd(0);
  acosd
---------
     90
(1 row)

确认0的反余弦正好是90°。

  • EVERY
create table book (id int,sal int ,bname string);

INSERT INTO book VALUES (1, 1, '1984');
INSERT INTO book VALUES (2, 1, 'Animal Farm');
INSERT INTO book VALUES (3, 2, 'O Alquimista');
INSERT INTO book VALUES (4, 2, 'Brida');

判断每本书的价格是否都小于10元

SELECT EVERY(sal < 10) FROM book;
  every
---------
  true
(1 row)

性能优化

  • 涵盖索引查询的性能优化。
  • 倒排索引查询的性能优化。
  • 优化了批量导入写入速度。
  • 当查找列不是表中的主键时,优化了表的查询速度。
  • 优化了副本之间的传输速度。
  • 优化了布尔类型列的统计分析,提高查询计划效率。
  • 减少了批量读取和索引缓冲区的内存使用。
  • 在涉及IN/NOT IN查询空元组或空数组的情况下,提升了执行计划效率。
  • 优化了一些包含谓词的选择性器。
  • 优化了矢量化执行引擎中的性能。

管理界面更改

  • 新版本页面整体风格的更改。
  • 监控界面新增三大模块,包含网络延迟模块、事务列表模块、会话列表模块。

网络延迟:主要显示集群及其各个节点的网络状况。

事务列表模块 :展现了平均事务时间,事务资源使用情况,界面展示了事务的执行次数、读取行数、读取字节数、连接时间、重试次数等。

会话列表:主要展现了会话的状态,包括时间等指标,也可以对会话进行中断操作。

BUG修复

  • 现在可以正确报告CHAR数据类型的类型长度。
  • 修复了age函数计算两个时间差值不正确的错误。
  • 修复了无法将各种会话变量设置为值onoff的错误,只能设置为truefalse
  • 修复了如果被除数为0的时候会有明显的error提示。
  • 修复了如果使用矢量化执行引擎,hubble在某些情况下运行带有CAST操作的查询时可能返回内部错误的情况。
  • 修复了使用向量化执行引擎时在特殊情况下可能崩溃的错误。
  • 修复了protobuf(protobuf是一个网络通信协议,它提供了高效率的序列化与反序列化机制)解码中的错误。
  • 修复了在个别情况下大事务中执行大量语句而不提交会使hubble服务器不稳定的情况。
  • 修复了内存泄漏,该泄漏可能会影响执行大表扫描的更改。

新增功能

函数索引

  • 表达式索引是通过将表达式应用于列而创建的索引
create table expression_index (id int PRIMARY KEY ,name string,tel string,sex string ,remark jsonb);

CREATE INDEX remark_index ON expression_index (parse_timestamp(remark->>'birthdate'));
		 
insert into expression_index values(1,'杨洋','1111','男',jsonb '{"id":"1","name": "杨洋","tel": "1111","sex": "男","birthdate":"1991-9-9"}' ),(2,'刘亦菲','2222','女',jsonb '{"id":"2","name": "刘亦菲","tel": "2222","sex": "女","birthdate":"1987-8-25"}' ); 

查看执行计划

explain select jsonb_pretty(remark) from expression_index where parse_timestamp(remark->>'birthdate') = '1987-8-25';
                                         info
--------------------------------------------------------------------------------------
  distribution: local
  vectorized: true

  • render
  │ estimated row count: 1
  │
  └── • index join
      │ estimated row count: 1
      │ table: expression_index@expression_index_pkey
      │
      └── • scan
            estimated row count: 2 (99% of the table; stats collected 3 minutes ago)
            table: expression_index@remark_index
            spans: [/'1987-08-25 00:00:00' - /'1987-08-25 00:00:00']
(14 rows)

hubble慢sql设置与分析

hubble数据库如果SQL语句返回意外结果或处理时间超过预期,则可以通过设置来输出查看慢sql。

慢sql日志设置

  • 设置 sql.log.slow_query.latency_threshold 为您所选择的阈值。例如,60秒表示用户感觉到的系统在瞬间做出反应的极限。
SET CLUSTER SETTING sql.log.slow_query.latency_threshold = '60s';
  • 要将慢速内部查询写入一个单独的日志,请将 sql.log.slow_query.internal_queries.enabled 集群设置为 true
SET CLUSTER SETTING sql.log.slow_query.internal_queries.enabled = 'true';
  • 每个节点的慢SQL日志默认写入hubble数据库日志目录下

慢sql日志查询

进入hubble数据库日志目录 /data/hubbledir310/logs/ 查看sql-slow.log文件

[root@poc-hubble04 logs]# cd /data/hubbledir310/logs/


[root@poc-hubble04 logs]# tail -n 4 hubble310-sql-slow.log
I220613 08:57:03.414866 1147934625 util/log/file_sync_buffer.go:238 ⋮ [config]   log format (utf8=): hubdb-v2
I220613 08:57:03.414873 1147934625 util/log/file_sync_buffer.go:238 ⋮ [config]   line format: [IWEF]yymmdd hh:mm:ss.uuuuuu goid [chan@]file:lineredactionmark \[tags\] [counter] msg
I220613 08:57:03.412822 1147934625 10@util/log/event_log.go:32 ⋮ [n3,client=‹192.168.1.11:50628›,hostssl,user=root] 1 ={"Timestamp":1655110514810544287,"EventType":"slow_query","Statement":"‹SELECT * FROM \"\".\"\".bptfhist_2y2 AS t WHERE main_ac LIKE '%10268427281' LIMIT 2›","Tag":"SELECT","User":"root","ApplicationName":"$ hubble sql","ExecMode":"exec","Age":108602.01,"FullTableScan":true,"TxnCounter":6}

其它新增

  • 新增执行语句超时时间设置

sql.defaults.statement_timeout 设置最大语句执行时长(单位秒), 默认值0。

  • 新增了session变量传参设置功能options
jdbc:postgresql://xx:35432/defaultdb?ssl=true&sslmode=require&options=--statement_timeout=1000