openGauss真的比PostgreSQL差了10年?

前不久写了MogDB针对PostgreSQL的兼容性文章,我在文中提到针对PostgreSQL而言,MogDB兼容性还是不错的,其中也给出了其中一个能源客户之前POC的迁移报告数据。

But很快我发现总有人回留言喷我,而且我发现每次喷的这帮人是根本不看文章内容的,完全就是看了标题就开喷,真是一喷为快!

针对如此多的后台留言,这里为提炼一下,同时我也来尝试“诡辩”一下!

MogDB是基于openGauss,而openGauss是基于PG9.2,现在PG都16了,最差了这么多代,你们还好意思说?

首先我要说下,针对是这个想法的这些有网友,你们真的看了文章内容吗?原生pg是多进程架构,而魔改之后的openGauss是线程架构,架构都不一样了呢,毫不夸张的说,基本上是完全不同的两款数据库产品了。

因此,就谈不上什么版本差了很多代的说法了呢。

那么如果说基于openGauss迭代的MogDB具具备了PG新版本所具有的一些功能,你们又该如何评价呢?

这里我就特意挑选几个小的点!

MogDB支持全局索引而PG不支持

记得前几天PG界的第一红网德哥就吐槽说,PG不支持全局索引。当时我看了之后,我心里一阵纳闷!

不支持全局索引的数据库,这tm的能用吗?这不搞笑的吗?

首先我给大家看下MogDB对于分区表的全局索引支持情况,废话不多说,直接上测试结果:

[omm2@mogdb1 ~]$ gsql -r -d test -U roger
Password for user roger: 
gsql ((MogDB 5.0.7 build c4707384) compiled at 2024-05-24 10:51:53 commit 0 last mr 1804 )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

test=> CREATE TABLE list_list
test-> (
test(>     month_code VARCHAR2 ( 30 ) NOT NULL ,
test(>     dept_code  VARCHAR2 ( 30 ) NOT NULL ,
test(>     user_no    VARCHAR2 ( 30 ) NOT NULL ,
test(>     sales_amt  int
test(> )
test-> PARTITION BY LIST (month_code) SUBPARTITION BY LIST (dept_code)
test-> (
test(>   PARTITION p_201901 VALUES ( '201902' )
test(>   (
test(>     SUBPARTITION p_201901_a VALUES ( '1' ),
test(>     SUBPARTITION p_201901_b VALUES ( '2' )
test(>   ),
test(>   PARTITION p_201902 VALUES ( '201903' )
test(>   (
test(>     SUBPARTITION p_201902_a VALUES ( '1' ),
test(>     SUBPARTITION p_201902_b VALUES ( '2' )
test(>   )
test(> );
CREATE TABLE
test=> insert into list_list values('201902''1''1', 1);
INSERT 0 1
test=> insert into list_list values('201902''2''1', 1);
INSERT 0 1
test=> insert into list_list values('201902''1''1', 1);
INSERT 0 1
test=> insert into list_list values('201903''2''1', 1);
INSERT 0 1
test=> insert into list_list values('201903''1''1', 1);
INSERT 0 1
test=> insert into list_list values('201903''2''1', 1);
INSERT 0 1
test=> create index idx_list_list on list_list(user_no) global;
CREATE INDEX
test=> explain select * from list_list where user_no=1;
                                  QUERY PLAN                                  
------------------------------------------------------------------------------
 Partition Iterator  (cost=0.00..14.57 rows=2 width=238)
   Iterations: 2, Sub Iterations: 4
   Selected Partitions:  1..2
   Selected Subpartitions:  1:ALL, 2:ALL
   ->  Partitioned Seq Scan on list_list  (cost=0.00..14.57 rows=2 width=238)
         Filter: ((user_no)::bigint = 1)
(6 rows)

test=> \di+
                                                     List of relations
 Schema |          Name           |          Type          | Owner |      Table       |    Size    | Storage | Description 
--------+-------------------------+------------------------+-------+------------------+------------+---------+-------------
 public | index_prune_tt01        | index                  | omm2  | prune_tt01       | 64 kB      |         | 
 public | table_1188398_2_pk      | index                  | omm2  | table_1188398_2  | 16 kB      |         | 
 roger  | idx_list_list           | global partition index | roger | list_list        | 16 kB      |         | 
 roger  | idx_test01_objectid     | index                  | roger | test01           | 245 MB     |         | 
 roger  | idx_test01_owner        | index                  | roger | test01           | 248 MB     |         | 
 roger  | t2_pkey                 | index                  | roger | t2               | 8192 bytes |         | 
 roger  | test_incresort_1_id_idx | index                  | roger | test_incresort_1 | 301 MB     |         | 
(7 rows)

大家可以看到这个分区的创建与法基本上跟Oracle一致,哪怕是二级分区,也支持创建global index的。

接下来我们看看PostgreSQL 13是否支持在分区表上创建Global Index。

postgres_5432@mogdb3 bin]$ ./psql
psql (13.2)
Type "help" for help.

postgres=# select version();
                                                version                                                 
---------------------------------------------------------------------------------------------------------
PostgreSQL 13.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit
(1 row)

postgres=#   CREATE TABLE list_list
postgres-#  (
postgres(#      month_code VARCHAR2 ( 30 ) NOT NULL ,
postgres(#      dept_code  VARCHAR2 ( 30 ) NOT NULL ,
postgres(#      user_no    VARCHAR2 ( 30 ) NOT NULL ,
postgres(#      sales_amt  int
postgres(#  )
postgres-#  PARTITION BY LIST (month_code) SUBPARTITION BY LIST (dept_code)
postgres-#  (
postgres(#    PARTITION p_201901 VALUES ( '201902' )
postgres(#    (
postgres(#      SUBPARTITION p_201901_a VALUES ( '1' ),
postgres(#      SUBPARTITION p_201901_b VALUES ( '2' )
postgres(#    ),
postgres(#    PARTITION p_201902 VALUES ( '201903' )
postgres(#    (
postgres(#      SUBPARTITION p_201902_a VALUES ( '1' ),
postgres(#      SUBPARTITION p_201902_b VALUES ( '2' )
postgres(#    )
postgres(#  );
ERROR:  syntax error at or near "SUBPARTITION"
LINE 8:  PARTITION BY LIST (month_code) SUBPARTITION BY LIST (dept_c...
                                       ^
postgres=#   
postgres=# CREATE TABLE measurement (
postgres(#     city_id         int not null,
postgres(#     logdate         date not null,
postgres(#     peaktemp        int,
postgres(#     unitsales       int
postgres(# ) PARTITION BY RANGE (logdate);
CREATE TABLE
postgres=
postgres=
postgres=# create table measurement_2022_1 partition of measurement
postgres-# for values from ('2022-01-01') to ('2022-02-01');
CREATE TABLE
postgres=
postgres=#  create table measurement_2022_2 partition of measurement
postgres-# for values from ('2022-02-01') to ('2022-03-01');
CREATE TABLE
postgres=
postgres=#  create table measurement_2022_3 partition of measurement
postgres-#  for values from ('2022-03-01') to ('2022-04-01');
CREATE TABLE
postgres=
postgres=# create index idx_measurement_date on measurement(logdate) global;
ERROR:  syntax error at or near "global"
LINE 1: ...e index idx_measurement_date on measurement(logdate) global;
                                                               ^
postgres=# create index idx_measurement_date on measurement(logdate);
CREATE INDEX

postgres=# insert into measurement(city_id,logdate,peaktemp,unitsales)  values(1,'2022-01-01',1,1);
INSERT 0 1
postgres=# insert into measurement(city_id,logdate,peaktemp,unitsales)  values(2,'2022-02-01',2,2);
INSERT 0 1
postgres=# insert into measurement(city_id,logdate,peaktemp,unitsales)  values(3,'2022-03-01',3,3);
INSERT 0 1
postgres=# \di+
                                                        List of relations
Schema |              Name              |       Type        |  Owner   |       Table        | Persistence |  Size   | Description 
--------+--------------------------------+-------------------+----------+--------------------+-------------+---------+-------------
public | idx_measurement_date           | partitioned index | postgres | measurement        | permanent   | 0 bytes | 
public | measurement_2022_1_logdate_idx | index             | postgres | measurement_2022_1 | permanent   | 16 kB   | 
public | measurement_2022_2_logdate_idx | index             | postgres | measurement_2022_2 | permanent   | 16 kB   | 
public | measurement_2022_3_logdate_idx | index             | postgres | measurement_2022_3 | permanent   | 16 kB   | 
(4 rows)

postgres=
ostgres=# explain select * from measurement where logdate > '2022-02-01';
                                            QUERY PLAN                                              
-----------------------------------------------------------------------------------------------------
Append  (cost=8.93..59.46 rows=1234 width=16)
  ->  Bitmap Heap Scan on measurement_2022_2 measurement_1  (cost=8.93..26.65 rows=617 width=16)
        Recheck Cond: (logdate > '2022-02-01'::date)
        ->  Bitmap Index Scan on measurement_2022_2_logdate_idx  (cost=0.00..8.78 rows=617 width=0)
              Index Cond: (logdate > '2022-02-01'::date)
  ->  Bitmap Heap Scan on measurement_2022_3 measurement_2  (cost=8.93..26.65 rows=617 width=16)
        Recheck Cond: (logdate > '2022-02-01'::date)
        ->  Bitmap Index Scan on measurement_2022_3_logdate_idx  (cost=0.00..8.78 rows=617 width=0)
              Index Cond: (logdate > '2022-02-01'::date)
(9 rows)

Time: 0.792 ms
postgres=# select * from measurement where logdate > '2022-02-01';
city_id |  logdate   | peaktemp | unitsales 
---------+------------+----------+-----------
      3 | 2022-03-01 |        3 |         3
(1 row)

Time: 0.491 ms

这是什么鬼?实际上我们可以看到PG的分区创建方式是有所区别的,简单的讲,其子分区已经是一个独立的表了,独立的文件。

不过从原理上来讲,我认为没有全局索引,还是一定程度上会影响查询性能,虽然local index其实也足够用了。

这个给大家举个例子,记得2014年去给某头部快递公司做数据库优化时(用的是Oracle exdata),发现一个访问非常高频的大表上的索引创建就不合理。

可能之前DBA是为了维护方便,索引几乎都是清一色的local分区,然而后面发现SQL的逻辑读非常高,在双11来临之前改成global index之后,逻辑读降低了数倍。当然最后系统CPU也降低了很多。

PG16新增的几个json函数,MogDB已经支持了

第二小的点是Postsql16新增的几个json处理函数,实际上MogDB 早就支持了。

大家可以参考pg的官方文档:https://www.postgresql.org/docs/16/release-16.html

[omm2@mogdb1 bin]$ gsql -r
gsql ((MogDB 5.0.7 build c4707384) compiled at 2024-05-24 10:51:53 commit 0 last mr 1804 )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

MogDB=# \c dbm
Non-SSL connection (SSL connection is recommended when requiring high-security)
You are now connected to database "dbm" as user "omm2".
dbm=
dbm=# select json_array(1,'a','b',true,null);
        json_array         
---------------------------
 [1, "a""b"true, null]
(1 row)

dbm=#  CREATE TEMP TABLE foo1 (serial_num int, name text, type text);
CREATE TABLE
dbm=# INSERT INTO foo1 VALUES (847001,'t15','GE1043');
INSERT 0 1
dbm=# INSERT INTO foo1 VALUES (847002,'t16','GE1043');
INSERT 0 1
dbm=# INSERT INTO foo1 VALUES (847003,'sub-alpha','GESS90');
INSERT 0 1
dbm=# SELECT json_arrayagg(type) from foo1;
         json_arrayagg          
--------------------------------
 ["GE1043""GE1043""GESS90"]
(1 row)


dbm=# select json_object('{a,b,"a b c"}', '{a,1,1}');
              json_object              
---------------------------------------
 {"a" : "a""b" : "1""a b c" : "1"}
(1 row)

dbm=# select serial_num,JSON_OBJECTAGG(name,type) from foo1 group by serial_num;
 serial_num |     json_objectagg      
------------+-------------------------
     847003 | {"sub-alpha""GESS90"}
     847001 | {"t15""GE1043"}
     847002 | {"t16""GE1043"}
(3 rows)

dbm=

上述提到的几个函数,实际上我在PG13.2上测试发现是不支持的。

[postgres_5432@mogdb3 bin]$ ./psql
psql (13.2)
Type "help" for help.

postgres=# select json_array(1,'a','b',true,null);
ERROR:  function json_array(integer, unknown, unknown, boolean, unknown) does not exist
LINE 1: select json_array(1,'a','b',true,null);
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
postgres=#     
postgres=
postgres=# CREATE TEMP TABLE foo1 (serial_num int, name text, type text);
CREATE TABLE
postgres=# INSERT INTO foo1 VALUES (847001,'t15','GE1043');
INSERT 0 1
postgres=# INSERT INTO foo1 VALUES (847002,'t16','GE1043');
INSERT 0 1
postgres=# INSERT INTO foo1 VALUES (847003,'sub-alpha','GESS90');
INSERT 0 1
postgres=# SELECT json_arrayagg(type) from foo1;
ERROR:  function json_arrayagg(text) does not exist
LINE 1: SELECT json_arrayagg(type) from foo1;
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
postgres=

postgres=# select serial_num,JSON_OBJECTAGG(name,type) from foo1 group by serial_num;
ERROR:  function json_objectagg(text, text) does not exist
LINE 1: select serial_num,JSON_OBJECTAGG(name,type) from foo1 group ...
                          ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
postgres=

MogDB 排序算法并不比PG主流版本差

另外我在看PG16的new feature时发现提到在优化器方面又有一些改进,其中一点就是对于增量排序(Allow incremental sorts in more cases, including DISTINCT (David Rowley)。

这里我想说的是,MogDB在这方面实际上也做了一些努力,在MogDB 3.1版本之前其实还是比较慢的。不相信? 好吧,给你看看同为openGauss系的友商数据库性能。

orcl=# \copy mogdb_incresort_1 from '/tmp/MogDB_incresort_1.dat';
Time: 45158.913 ms
orcl=# select count(1) from mogdb_incresort_1;
  count   
----------
 10000000
(1 row)

Time: 3986.539 ms
orcl=#  select players.pname,
orcl-#      random() as lottery_number
orcl-#  from (
orcl(#          select distinct pname
orcl(#          from MogDB_incresort_1
orcl(#          group by pname
orcl(#          order by pname
orcl(#      ) as players
orcl-#  order by players.pname,
orcl-#      lottery_number
orcl-#  limit 20;
      pname       |  lottery_number   
------------------+-------------------
 player# 1        |  .693211137317121
 player# 10       |  .373950335662812
 player# 100      |  .748802043031901
 player# 1000     |  .868999985512346
 player# 10000    |  .708094645757228
 player# 100000   |  .146068200934678
 player# 1000000  |  .400482173077762
 player# 10000000 | .0748530034907162
 player# 1000001  |  .951222819741815
 player# 1000002  | .0985643910244107
 player# 1000003  |  .673836125060916
 player# 1000004  |  .493436659686267
 player# 1000005  |  .744129443541169
 player# 1000006  |   .45777113456279
 player# 1000007  |   .90621894877404
 player# 1000008  |  .818961981683969
 player# 1000009  |   .91224535740912
 player# 100001   |  .955949443858117
 player# 1000010  |  .175989827606827
 player# 1000011  | .0911367381922901
(20 rows)

Time: 33222.676 ms
orcl=# explain analyze
orcl-#  select players.pname,
orcl-#      random() as lottery_number
orcl-#  from (
orcl(#          select distinct pname
orcl(#          from MogDB_incresort_1
orcl(#          group by pname
orcl(#          order by pname
orcl(#      ) as players
orcl-#  order by players.pname,
orcl-#      lottery_number
orcl-#  limit 20;
                                                                              QUERY PLAN                                                                               
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=5984227.96..5984228.01 rows=20 width=128) (actual time=37477.723..37477.728 rows=20 loops=1)
   ->  Sort  (cost=5984227.96..6009228.03 rows=10000029 width=128) (actual time=37477.718..37477.719 rows=20 loops=1)
         Sort Key: players.pname, (random())
         Sort Method: top-N heapsort  Memory: 30kB
         ->  Subquery Scan on players  (cost=5518130.20..5718130.78 rows=10000029 width=128) (actual time=17705.988..34580.240 rows=10000000 loops=1)
               ->  Unique  (cost=5518130.20..5593130.42 rows=10000029 width=128) (actual time=17705.951..26398.773 rows=10000000 loops=1)
                     ->  Group  (cost=5518130.20..5568130.35 rows=10000029 width=128) (actual time=17705.947..23714.165 rows=10000000 loops=1)
                           Group By Key: mogdb_incresort_1.pname
                           ->  Sort  (cost=5518130.20..5543130.28 rows=10000029 width=128) (actual time=17705.940..20369.481 rows=10000000 loops=1)
                                 Sort Key: mogdb_incresort_1.pname
                                 Sort Method: external merge  Disk: 1350368kB
                                 ->  Seq Scan on mogdb_incresort_1  (cost=0.00..356411.29 rows=10000029 width=128) (actual time=0.020..2464.995 rows=10000000 loops=1)
 Total runtime: 37478.118 ms
(13 rows)

Time: 37480.533 ms

是的,你没有看错,这个简单的测试SQL 居然跑了30多秒。

那么我们来看在MogDB5.0.7版本中跑一下需要多久呢?

test=# \copy mogdb_incresort_1 from '/tmp/MogDB_incresort_1.dat';
test=# \timing on
test=# explain analyze
test-#  select players.pname,
test-#      random() as lottery_number
test-#  from (
test(#          select distinct pname
test(#          from MogDB_incresort_1
test(#          group by pname
test(#          order by pname
test(#      ) as players
test-#  order by players.pname,
test-#      lottery_number
test-#  limit 20;
                                                                             QUERY PLAN                                                                              
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=2174587.26..2174588.44 rows=20 width=64) (actual time=5315.519..5315.524 rows=20 loops=1)
   ->  Incremental Sort  (cost=2174587.26..2763354.30 rows=9999951 width=64) (actual time=5315.517..5315.518 rows=20 loops=1)
         Sort Key: players.pname, (random())
         Presorted Key: players.pname
         Full-sort Groups: 1  Sort Method: quicksort  Average Memory: 28kB Peak Memory: 28kB
         ->  Subquery Scan on players  (cost=2172256.79..2372255.81 rows=9999951 width=64) (actual time=5315.453..5315.487 rows=21 loops=1)
               ->  Unique  (cost=2172256.79..2247256.43 rows=9999951 width=64) (actual time=5315.433..5315.452 rows=21 loops=1)
                     ->  Group  (cost=2172256.79..2222256.55 rows=9999951 width=64) (actual time=5315.425..5315.442 rows=21 loops=1)
                           Group By Key: mogdb_incresort_1.pname
                           ->  Sort  (cost=2172256.79..2197256.67 rows=9999951 width=64) (actual time=5315.420..5315.425 rows=21 loops=1)
                                 Sort Key: mogdb_incresort_1.pname
                                 Sort Method: external merge  Disk: 665520kB
                                 ->  Seq Scan on mogdb_incresort_1  (cost=0.00..223456.51 rows=9999951 width=64) (actual time=0.012..1828.749 rows=10000000 loops=1)
 Total runtime: 5449.456 ms
(14 rows)

Time: 5457.669 ms
test=#  select players.pname,
test-#      random() as lottery_number
test-#  from (
test(#          select distinct pname
test(#          from MogDB_incresort_1
test(#          group by pname
test(#          order by pname
test(#      ) as players
test-#  order by players.pname,
test-#      lottery_number
test-#  limit 20;
      pname       |   lottery_number   
------------------+--------------------
 player# 1        |  0.579584513325244
 player# 10       |  0.836566388607025
 player# 100      |  0.843441488686949
 player# 1000     |  0.718995271716267
 player# 10000    |  0.892783336341381
 player# 100000   |   0.10398242296651
 player# 1000000  |  0.308310507796705
 player# 10000000 | 0.0168832587078214
 player# 1000001  |  0.446922336239368
 player# 1000002  | 0.0639159493148327
 player# 1000003  |  0.313714498188347
 player# 1000004  |  0.516515084076673
 player# 1000005  |  0.702487968374044
 player# 1000006  |  0.277854182291776
 player# 1000007  |  0.934525999706239
 player# 1000008  |   0.72923140367493
 player# 1000009  |  0.321010332554579
 player# 100001   |  0.651651729829609
 player# 1000010  |  0.506305878516287
 player# 1000011  |   0.46931520383805
(20 rows)

Time: 4521.001 ms
test=#   

大家可以看到,其实也就不到5s的样子的。还是比较快的。

最后我们看下相同的SQL在PG13中运行效率如何。

postgres=#  create table MogDB_incresort_1 (id int, pname name, match text);
CREATE TABLE
postgres=#  create index on MogDB_incresort_1(id);
CREATE INDEX
postgres=# insert into MogDB_incresort_1
postgres-#  values (
postgres(#          generate_series(1, 10000000),
postgres(#          'player# ' || generate_series(1, 10000000),
postgres(#          'match# ' || generate_series(1, 11)
postgres(#      );
 INSERT 0 10000000
postgres=#  
postgres=
postgres=#  select count(1) from MogDB_incresort_1;
  count   
----------
 10000000
(1 row)

postgres=#  vacuum analyze MogDB_incresort_1;
VACUUM
postgres=# \timing on
Timing is on.
postgres=#   set max_parallel_workers_per_gather = 0;
SET
Time: 0.250 ms
postgres=#  select players.pname,
postgres-#      random() as lottery_number
postgres-#  from (
postgres(#          select distinct pname
postgres(#          from MogDB_incresort_1
postgres(#          group by pname
postgres(#          order by pname
postgres(#      ) as players
postgres-#  order by players.pname,
postgres-#      lottery_number
postgres-#  limit 20;
      pname       |   lottery_number    
------------------+---------------------
 player# 1        |  0.0447521551191592
 player# 10       |   0.408278868270898
 player# 100      |  0.7921926875019913
 player# 1000     | 0.11271848207791635
 player# 10000    |  0.2647472418342467
 player# 100000   |  0.1412932234901234
 player# 1000000  |  0.4266691727193681
 player# 10000000 | 0.46474439957439273
 player# 1000001  | 0.23216838816411567
 player# 1000002  |  0.1229366164369452
 player# 1000003  |  0.3386561272461357
 player# 1000004  |  0.4146373941657302
 player# 1000005  | 0.28414336215408653
 player# 1000006  |  0.3686260468699629
 player# 1000007  |  0.1296536218416513
 player# 1000008  | 0.22829014039084683
 player# 1000009  | 0.15364363544027881
 player# 100001   | 0.08520628747068315
 player# 1000010  |   0.697556601432435
 player# 1000011  |  0.7879138632733813
(20 rows)

Time: 3637.823 ms (00:03.638)
postgres=# explain analyze
postgres-#  select players.pname,
postgres-#      random() as lottery_number
postgres-#  from (
postgres(#          select distinct pname
postgres(#          from MogDB_incresort_1
postgres(#          group by pname
postgres(#          order by pname
postgres(#      ) as players
postgres-#  order by players.pname,
postgres-#      lottery_number
postgres-#  limit 20;
                                                                              QUERY PLAN                                                                              
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=1765110.33..1765111.80 rows=20 width=72) (actual time=3759.205..3759.210 rows=20 loops=1)
   ->  Incremental Sort  (cost=1765110.33..2498764.46 rows=10000017 width=72) (actual time=3759.203..3759.206 rows=20 loops=1)
         Sort Key: players.pname, (random())
         Presorted Key: players.pname
         Full-sort Groups: 1  Sort Method: quicksort  Average Memory: 27kB  Peak Memory: 27kB
         ->  Subquery Scan on players  (cost=1762114.60..1962114.94 rows=10000017 width=72) (actual time=3759.173..3759.192 rows=21 loops=1)
               ->  Unique  (cost=1762114.60..1837114.73 rows=10000017 width=64) (actual time=3759.168..3759.184 rows=21 loops=1)
                     ->  Group  (cost=1762114.60..1812114.69 rows=10000017 width=64) (actual time=3759.167..3759.178 rows=21 loops=1)
                           Group Key: mogdb_incresort_1.pname
                           ->  Sort  (cost=1762114.60..1787114.64 rows=10000017 width=64) (actual time=3759.164..3759.169 rows=21 loops=1)
                                 Sort Key: mogdb_incresort_1.pname
                                 Sort Method: external merge  Disk: 724152kB
                                 ->  Seq Scan on mogdb_incresort_1  (cost=0.00..223457.17 rows=10000017 width=64) (actual time=0.010..1315.358 rows=10000000 loops=1)
 Planning Time: 0.095 ms
 Execution Time: 3897.663 ms
(15 rows)

Time: 3898.239 ms (00:03.898)
postgres=

我们可以看到实际上PG13版本也差不多需要4s左右。

而且细心一点的朋友还可以发现,其中的sort method部分,MogDB似乎看起来比pg13还要好一些。

后面我发现去年研发团队有同事分享过MogDB排序方面的知识,看pdf材料内容,其实应该是借鉴了PostgreSQL15的相关算法。

alt

好了,言归正传!

基于如上三点!所以你们还会觉得MogDB比PG差几代么?

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/38376.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024广州智能音箱展|广州蓝牙耳机展

2024广州智能音箱展|广州蓝牙耳机展 时间:2024年11月29日-12月1日 地点:广州琶洲保利世贸博览馆 【展会简介】 中国是全球最大的音频产品制造基地和消费市场,随着国内外互联网巨头纷纷瞄准音频行业并投入巨资布局AI产品矩阵,音…

pom.xml文件加载后没有变成maven图标

原因: 开启了IDEA的节电模式 现象为: xml会变橙色,yml变粉色,自动提示关闭等 把这个节能模式的勾选给取消掉就可以正常显示了

python提取图片中的文字写入excel文件,并打包为exe可执行文件

python提取图片数据写入excel,并打包为exe可执行文件 1. 以下面的图片为例2. python环境需要的依赖包3. 创建交互式窗口4. 读取文件夹下的所有文件并提取数据5. 提取图片中字段的代码6. 打包代码为exe可执行文件安装打包依赖文件运行打包代码 1. 以下面的图片为例 2…

入门Salesforce:必须掌握的20+基础专业术语!

Salesforce的发展令人印象深刻。在过去的20年中,Salesforce创建了一个由管理员、开发人员、顾问和用户组成的生态系统,不断颠覆创新CRM,促进平等和多样性。 作为初学者,探索Salesforce领域就像学习一门新语言。Salesforce中有着大…

YOLOv8改进 | 卷积模块 | 减少冗余计算和内存访问的PConv【CVPR2023】

秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录 :《YOLOv8改进有效…

Vue3详解

vite和webpack区别 vite vite使用原生ES模块进行开发,无需在编译时将所有代码转换为JS打包,从而提供了更快的热更新和自动刷新功能; vite在开发模式下没有打包步骤,而是利用浏览器的ES Module Imports特性实现按需编译&#xff…

Firefox 编译指南2024 Windows10篇- 编译Firefox(三)

1.引言 在成功获取了Firefox源码之后,下一步就是将这些源码编译成一个可执行的浏览器。编译是开发流程中的关键环节,通过编译,我们可以将源代码转换为可执行的程序,测试其功能,并进行必要的优化和调试。 对于像Firef…

git命令含有中文,终端输出中文乱码的问题

目录 1、[当前代码页] 的936 (ANSI/OEM - 简体中文 GBK) 是导致中文乱码的原因 2、这样会导致什么问题呢? (1) 问题一: 【属性】选项的【字体】无法识别自定义文字样式,【默认值】选项可选自定义字体样式,却无法覆盖【属性】选项 (2) 问题…

品牌推广怎么样?掌握正确做法,让品牌大放异彩!

品牌推广对于初创公司来说是一项至关重要的任务。在市场众多品牌中,如何脱颖而出,是每个品牌方都要考虑的问题。 作为一名手工酸奶品牌的创始人,目前全国复制了100多家门店,我来分享下,如何推广,可以让品牌…

通过shell脚本创建MySQl数据库

通过shell脚本创建数据库 #!/bin/bashserverIP10.1.1.196 SERVER_NAMEecho $serverIP | cut -d . -f4cat<<EOF>db.sql drop database if exists ${SERVER_NAME}_scheduler; drop database if exists ${SERVER_NAME}_kms; drop database if exists ${SERVER_NAME}_uim…

Centos7修改yum源

安装好系统后&#xff0c;网络能通信&#xff0c;源也没有配置&#xff0c;但是安装软件失败。 解决办法&#xff1a;配置阿里yum源 # curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo # yum clean all # yum make cache再次安装软…

二分查找1

1. 二分查找&#xff08;704&#xff09; 题目描述&#xff1a; 算法原理&#xff1a; 暴力解法就是遍历数组来找到相应的元素&#xff0c;使用二分查找的解法就是每次在数组中选定一个元素来将数组划分为两部分&#xff0c;然后因为数组有序&#xff0c;所以通过大小关系舍弃…

七天速通javaSE:第五天 数组基础

文章目录 前言一、认识数组二、数组的声明和创建1. 声明数组变量2. 创建数组3. 变量的初始化&#xff08;赋值&#xff09;3.1 静态初始化3.2 动态初始化 3. 示例 三、数组的使用1. 循环1.1 普通for循环1.2 For-Each 循环 2. 数组作为函数的参数和返回值 前言 本文将为大家介绍…

Win11 Python3.10 安装pytorch3d

0&#xff0c;背景 Python3.10、cuda 11.7、pytorch 2.0.1 阅读【深度学习】【三维重建】windows10环境配置PyTorch3d详细教程-CSDN博客 1&#xff0c;解决方法 本来想尝试&#xff0c;结果发现CUB安装配置对照表里没有cuda 11.7对应的版本&#xff0c;不敢轻举妄动&#x…

DP:子序列问题

文章目录 什么是子序列子序列的特点举例说明常见问题 关于子序列问题的几个例题1.最长递增子序列2.摆动序列3.最长递增子序列的个数4.最长数对链5.最长定差子序列 总结 什么是子序列 在计算机科学和数学中&#xff0c;子序列&#xff08;Subsequence&#xff09;是指从一个序列…

c语言的烫烫烫烫烫??

当初学习C语言时&#xff0c;对于一些特殊的打印输出可能会感到困惑&#xff0c;比如会出现一堆乱码烫烫烫的情况。其实这是因为在C语言中&#xff0c;对于字符类型和数字类型之间的隐式转换可能会导致打印输出的结果不符合预期。这并不意味着程序员"烫"&#xff0c;…

[激光原理与应用-96]:激光器研发与生产所要的常见设备(大全)与仪器(图解)

目录 一、激光器制造设备 二、测试与校准设备 2.1 光功率计&#xff1a; 1、工作原理 2、主要功能 3、应用场景 4、测量方法 5、总结 2.2. 激光束质量分析仪&#xff1a; 1、概述 2、主要功能和特点 3、工作原理 4、常见品牌和型号 5、应用领域 6、总结 2.3 光…

基于大数据架构的情感分析

1 项目介绍 1.1 研究目的和意义 随着大数据时代的到来&#xff0c;电影产业积累了海量的用户评论数据&#xff0c;这些数据中蕴含着观众的情感倾向与偏好信息&#xff0c;为电影推荐和市场策略制定提供了宝贵资源。然而&#xff0c;如何高效地从这浩瀚的数据海洋中提炼出有价…

QT5:在窗口右上角显示图标

目录 一、环境与目标 二、实现逻辑&#xff08;纯代码&#xff09;与效果 三、参考代码 四、总结 一、环境与目标 qt版本&#xff1a;5.12.7 windows 11 下的 Qt Designer &#xff08;已搭建&#xff09; 目标&#xff1a;使用嵌套布局的方式将两个按钮显示在窗口右上角…

《大海》这歌为何经久不衰?你看歌词写的多美妙!

《大海》这歌为何经久不衰&#xff1f;你看歌词写的多美妙&#xff01; 《大海》是一首由陈大力作词&#xff0c;陈大力、陈秀男作曲&#xff0c;Ricky Ho编曲&#xff0c;张雨生演唱的国语流行歌曲。该曲收录在张雨生1992年11月30日由飞碟唱片发行的同名专辑《大海》中。 作为…