对基于 Greenplum Database 的操作,HybridDB for PostgreSQL 与 Greenplum Database 开源数据库基本一致,包括 schema、类型支持、用户权限等。除 Greenplum Database 开源数据库一些特有的操作,如分布键、AO表等,其它操作皆可参见 PostgreSQL。

本文介绍了 HybridDB for PostgreSQL 的基础操作:创建数据库、创建分布键和查询。

创建数据库

HybridDB for PostgreSQL 中创建数据库的操作与 PostgreSQL 相同,可以通过 SQL 来执行,如在 psql 连接到 Greenplum 后执行如下命令:

=> create database mygpdb;
CREATE DATABASE
=> \c mygpdb
psql (9.4.4, server 8.3devel)
You are now connected to database "mygpdb" as user "mygpdb".

创建分布键

在 HybridDB for PostgreSQL 中,表分布在所有的 Segment 上,其分布规则是 HASH 或者随机。在建表时,指定分布键;当导入数据时,会根据分布键计算得到的 HASH 值分配到特定的 Segment 上。

=> create table vtbl(id serial, key integer, value text, shape cuboid, location geometry, comment text) distributed by (key);
CREATE TABLE

当不指定分布键时(即不带后面的distributed by (key)时),Greenplum 会默认对 id 字段以 round-robin 的方式进行随机分配。

关于分布键

分布键对于查询性能至关重要。“均匀”为分布键选择的第一大原则,选取更有业务意义的字段,将有助于显著提高性能。

  • 尽量选择分布均匀的列、或者多列,以防止数据倾斜。

  • 尽量选择常用于连接运算的字段,对于并发较高的语句,该选择更为重要。

  • 尽量选择高并发查询、过滤性高的条件列。

  • 尽量不要轻易使用随机分布。

详细内容,请参见本文档参考中内容。

构造数据

  1. 创建函数,用于生成随机字符串。

    CREATE OR REPLACE FUNCTION random_string(integer) RETURNS text AS $body$
    SELECT array_to_string(array
                          (SELECT substring('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
                                            FROM (ceil(random()*62))::int
                                            FOR 1)
                           FROM generate_series(1, $1)), ''); 
    $body$ 
    LANGUAGE SQL VOLATILE;
  2. 创建分布键。

    CREATE TABLE tbl(id serial, KEY integer, locate geometry, COMMENT text) distributed by (key);
  3. 构造数据。

    INSERT INTO tbl(KEY, COMMENT, locate) 
     SELECT 
         KEY, 
         COMMENT, 
         ST_GeomFromText(locate) AS locate 
     FROM
         (SELECT 
             (a + 1) AS KEY, 
             random_string(ceil(random() * 24)::integer) AS COMMENT, 
             'POINT(' || ceil(random() * 36 + 99) || ' ' || ceil(random() * 24 + 50) || ')' AS locate 
         FROM 
             generate_series(0, 99999) AS a) 
         AS t;

查询示例

  • 查询

      => select * from tbl where key = 751;
      | id  | key | value | shape        | locate                                     | comment        |
      +-----+-----+-------+--------------+--------------------------------------------+----------------+
      | 751 | 751 | red   | 01010000000000000000C05B400000000000004A40 | B9hPhjeNWPqV |
      (1 row)
      Time: 513.101 ms
  • 查询计划

      => explain select * from tbl where key = 751;
      Gather Motion 1:1  (slice1; segments: 1)  (cost=0.00..1519.28 rows=1 width=53)
        ->  Seq Scan on tbl  (cost=0.00..1519.28 rows=1 width=53)
              Filter: key = 751
      Settings:  effective_cache_size=8GB; gp_statistics_use_fkeys=on
      Optimizer status: legacy query optimizer

参考