• PostgreSQL和PPAS的分区表及多种条件下的性能体现二


    PPAS中的分区表可以按oracle兼容的语法创建,具体使用请参见《Postgres_Plus_Advanced_Server_Oracle_Compatibility_Guide_v91.pdf》。
    下面是分区表上操作的相关情况

    1
    创建表:
    create table test (id integer primary key, name varchar(32))
    PARTITION BY RANGE (id)
    (PARTITION t1_1000 VALUES LESS THAN(1001),
     PARTITION t1001_2000 VALUES LESS THAN(2001),
     PARTITION t2001_3000 VALUES LESS THAN(3001));

    1.1
    从数据库取的表定义
    -- Table: test
    -- DROP TABLE test;
    CREATE TABLE test
    (
      id integer NOT NULL,
      name character varying(32),
      CONSTRAINT test_pkey PRIMARY KEY (id)
    )
    WITH (
      OIDS=FALSE
    );
    ALTER TABLE test
      OWNER TO enterprisedb;


    -- Table: test_t1_1000
    -- DROP TABLE test_t1_1000;
    CREATE TABLE test_t1_1000
    (
    -- Inherited from table test:  id integer NOT NULL,
    -- Inherited from table test:  name character varying(32),
      CONSTRAINT test_t1_1000_pkey PRIMARY KEY (id),
      CONSTRAINT test_t1_1000_partition CHECK (id < 1001)
    )
    INHERITS (test)
    WITH (
      OIDS=FALSE
    );
    ALTER TABLE test_t1_1000
      OWNER TO enterprisedb;

    -- Table: test_t1001_2000
    -- DROP TABLE test_t1001_2000;
    CREATE TABLE test_t1001_2000
    (
    -- Inherited from table test:  id integer NOT NULL,
    -- Inherited from table test:  name character varying(32),
      CONSTRAINT test_t1001_2000_pkey PRIMARY KEY (id),
      CONSTRAINT test_t1001_2000_partition CHECK (id >= 1001 AND id < 2001)
    )
    INHERITS (test)
    WITH (
      OIDS=FALSE
    );
    ALTER TABLE test_t1001_2000
      OWNER TO enterprisedb;


    -- Table: test_t2001_3000
    -- DROP TABLE test_t2001_3000;
    CREATE TABLE test_t2001_3000
    (
    -- Inherited from table test:  id integer NOT NULL,
    -- Inherited from table test:  name character varying(32),
      CONSTRAINT test_t2001_3000_pkey PRIMARY KEY (id),
      CONSTRAINT test_t2001_3000_partition CHECK (id >= 2001 AND id < 3001)
    )
    INHERITS (test)
    WITH (
      OIDS=FALSE
    );
    ALTER TABLE test_t2001_3000
      OWNER TO enterprisedb;

    2
    给表中插入值时自动根据ID值插入到分区表中
    edbtest=# INSERT INTO test(id, name)VALUES (6, 'ertr');
    INSERT 0 0

    edbtest=# select * from test;
     id | name
    ----+------
      6 | ertr
    (1 row)

    edbtest=#
    edbtest=# select count(*) from only test;
     count
    -------
         0
    (1 row)

    edbtest=# select count(*) from only test_t1_1000;
     count
    -------
         1
    (1 row)
                                      ^
    edbtest=#
    edbtest=# select count(*) from only test_t1001_2000;
     count
    -------
         0
    (1 row)

    edbtest=#

    3
    从父表中删除该值
    edbtest=# delete from test where id=6;
    DELETE 1
    edbtest=#
    edbtest=# select count(*) from only test_t1_1000;
     count
    -------
         0
    (1 row)

    4
    批量插入值
    edbtest=#insert into test select generate_series(1,2600),'abc';
    INSERT 0 0
    edbtest=#
    edbtest=# select count(*) from test;
     count
    -------
      2600
    (1 row)

    edbtest=# select count(*) from only test;
     count
    -------
         0
    (1 row)

    edbtest=# select count(*) from only test_t2001_3000;
     count
    -------
       600
    (1 row)

    edbtest=#

    5
    查询

    5.1
    按分区列值查询,只查询对应分区表
    edbtest=# explain select * from test where id=200;
                                                  QUERY PLAN                                              
    -------------------------------------------------------------------------------------------------------
     Result  (cost=0.00..7.27 rows=2 width=47)
       ->  Append  (cost=0.00..7.27 rows=2 width=47)
             ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=86)
                   Filter: (id = 200)
             ->  Index Scan using test_t1_1000_pkey on test_t1_1000 test  (cost=0.00..7.27 rows=1 width=8)
                   Index Cond: (id = 200)
    (6 rows)

    5.2
    按分区列值做范围查询,只查询对应分区表
    edbtest=# explain select * from test where id<200 and id>100;
                                                   QUERY PLAN                                               
    ---------------------------------------------------------------------------------------------------------
     Result  (cost=0.00..9.25 rows=101 width=9)
       ->  Append  (cost=0.00..9.25 rows=101 width=9)
             ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=86)
                   Filter: ((id < 200) AND (id > 100))
             ->  Index Scan using test_t1_1000_pkey on test_t1_1000 test  (cost=0.00..9.25 rows=100 width=8)
                   Index Cond: ((id < 200) AND (id > 100))
    (6 rows)

    edbtest=#

    edbtest=# explain select * from test where id<700 and id>100;
                                       QUERY PLAN                                  
    --------------------------------------------------------------------------------
     Result  (cost=0.00..20.00 rows=601 width=8)
       ->  Append  (cost=0.00..20.00 rows=601 width=8)
             ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=86)
                   Filter: ((id < 700) AND (id > 100))
             ->  Seq Scan on test_t1_1000 test  (cost=0.00..20.00 rows=600 width=8)
                   Filter: ((id < 700) AND (id > 100))
    (6 rows)

    edbtest=#
    edbtest=# explain select * from test where id<1100 and id>900;
                                                      QUERY PLAN                                                  
    ---------------------------------------------------------------------------------------------------------------
     Result  (cost=0.00..18.50 rows=201 width=8)
       ->  Append  (cost=0.00..18.50 rows=201 width=8)
             ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=86)
                   Filter: ((id < 1100) AND (id > 900))
             ->  Index Scan using test_t1_1000_pkey on test_t1_1000 test  (cost=0.00..9.25 rows=100 width=8)
                   Index Cond: ((id < 1100) AND (id > 900))
             ->  Index Scan using test_t1001_2000_pkey on test_t1001_2000 test  (cost=0.00..9.25 rows=100 width=8)
                   Index Cond: ((id < 1100) AND (id > 900))
    (8 rows)

    5.3
    按分区列值和其它列查询,只查询对应分区表
    edbtest=# explain select * from test where id=300 and name='ccc';
                                                  QUERY PLAN                                              
    -------------------------------------------------------------------------------------------------------
     Result  (cost=0.00..7.27 rows=2 width=47)
       ->  Append  (cost=0.00..7.27 rows=2 width=47)
             ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=86)
                   Filter: ((id = 300) AND ((name)::text = 'ccc'::text))
             ->  Index Scan using test_t1_1000_pkey on test_t1_1000 test  (cost=0.00..7.27 rows=1 width=8)
                   Index Cond: (id = 300)
                   Filter: ((name)::text = 'ccc'::text)
    (7 rows)

    5.4
    按分区列值查询,值有显式类型转换,只查询对应分区表
    edbtest=# explain select * from test where id='5'::int;
                                                  QUERY PLAN                                              
    -------------------------------------------------------------------------------------------------------
     Result  (cost=0.00..7.27 rows=2 width=47)
       ->  Append  (cost=0.00..7.27 rows=2 width=47)
             ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=86)
                   Filter: (id = 5)
             ->  Index Scan using test_t1_1000_pkey on test_t1_1000 test  (cost=0.00..7.27 rows=1 width=8)
                   Index Cond: (id = 5)
    (6 rows)

    5.5
    按分区列值查询,值和列类型不同,值有隐式类型转换,只查询对应分区表
    edbtest=# explain select * from test where id='5';
                                                  QUERY PLAN                                              
    -------------------------------------------------------------------------------------------------------
     Result  (cost=0.00..7.27 rows=2 width=47)
       ->  Append  (cost=0.00..7.27 rows=2 width=47)
             ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=86)
                   Filter: (id = 5)
             ->  Index Scan using test_t1_1000_pkey on test_t1_1000 test  (cost=0.00..7.27 rows=1 width=8)
                   Index Cond: (id = 5)
    (6 rows)


    5.6
    按分区列值查询,列要做隐式类型转换,走全表扫描
    edbtest=# explain select * from test where id || name ='5abc';
                                       QUERY PLAN                                   
    ---------------------------------------------------------------------------------
     Result  (cost=0.00..65.00 rows=14 width=14)
       ->  Append  (cost=0.00..65.00 rows=14 width=14)
             ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=86)
                   Filter: (((id)::text || (name)::text) = '5abc'::text)
             ->  Seq Scan on test_t1_1000 test  (cost=0.00..25.00 rows=5 width=8)
                   Filter: (((id)::text || (name)::text) = '5abc'::text)
             ->  Seq Scan on test_t1001_2000 test  (cost=0.00..25.00 rows=5 width=8)
                   Filter: (((id)::text || (name)::text) = '5abc'::text)
             ->  Seq Scan on test_t2001_3000 test  (cost=0.00..15.00 rows=3 width=8)
                   Filter: (((id)::text || (name)::text) = '5abc'::text)
    (10 rows)

    edbtest=#

    5.7
    按分区列值查询,值使用了函数,走全表扫描
    edbtest=# explain select * from test where id=to_number('1');
                                       QUERY PLAN                                   
    ---------------------------------------------------------------------------------
     Result  (cost=0.00..52.00 rows=14 width=14)
       ->  Append  (cost=0.00..52.00 rows=14 width=14)
             ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=86)
                   Filter: ((id)::numeric = 1::numeric)
             ->  Seq Scan on test_t1_1000 test  (cost=0.00..20.00 rows=5 width=8)
                   Filter: ((id)::numeric = 1::numeric)
             ->  Seq Scan on test_t1001_2000 test  (cost=0.00..20.00 rows=5 width=8)
                   Filter: ((id)::numeric = 1::numeric)
             ->  Seq Scan on test_t2001_3000 test  (cost=0.00..12.00 rows=3 width=8)
                   Filter: ((id)::numeric = 1::numeric)
    (10 rows)

    5.8
    按分区列值查询,值使用了函数,走分区表索引扫描
    edbtest=# explain select * from test where id=cast('1' as int);
                                                  QUERY PLAN                                              
    -------------------------------------------------------------------------------------------------------
     Result  (cost=0.00..7.27 rows=2 width=47)
       ->  Append  (cost=0.00..7.27 rows=2 width=47)
             ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=86)
                   Filter: (id = 1)
             ->  Index Scan using test_t1_1000_pkey on test_t1_1000 test  (cost=0.00..7.27 rows=1 width=8)
                   Index Cond: (id = 1)
    (6 rows)

    edbtest=#

    5.9
    按分区列值查询,值使用了子查询,用等号走全表扫描,用in走分区表索引扫描
    edbtest=# explain select * from test where id in(select 1 from dual);
                                                  QUERY PLAN                                              
    -------------------------------------------------------------------------------------------------------
     Nested Loop Semi Join  (cost=0.00..8.31 rows=2 width=47)
       ->  Append  (cost=0.00..7.27 rows=2 width=47)
             ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=86)
                   Filter: (id = 1)
             ->  Index Scan using test_t1_1000_pkey on test_t1_1000 test  (cost=0.00..7.27 rows=1 width=8)
                   Index Cond: (id = 1)
       ->  Materialize  (cost=0.00..1.01 rows=1 width=0)
             ->  Seq Scan on dual  (cost=0.00..1.01 rows=1 width=0)
    (8 rows)

    edbtest=# explain select * from test where id =(select 1 from dual);
                                                     QUERY PLAN                                                 
    -------------------------------------------------------------------------------------------------------------
     Result  (cost=1.01..22.82 rows=4 width=28)
       InitPlan 1 (returns $0)
         ->  Seq Scan on dual  (cost=0.00..1.01 rows=1 width=0)
       ->  Append  (cost=0.00..21.81 rows=4 width=28)
             ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=86)
                   Filter: (id = $0)
             ->  Index Scan using test_t1_1000_pkey on test_t1_1000 test  (cost=0.00..7.27 rows=1 width=8)
                   Index Cond: (id = $0)
             ->  Index Scan using test_t1001_2000_pkey on test_t1001_2000 test  (cost=0.00..7.27 rows=1 width=8)
                   Index Cond: (id = $0)
             ->  Index Scan using test_t2001_3000_pkey on test_t2001_3000 test  (cost=0.00..7.27 rows=1 width=8)
                   Index Cond: (id = $0)
    (12 rows)

    edbtest=#

    5.10
    按分区列值 更新,走分区表索引扫描
    edbtest=# explain update test set name = 'bbb' where id=99;
                                                QUERY PLAN                                           
    --------------------------------------------------------------------------------------------------
     Update on test  (cost=0.00..7.27 rows=2 width=10)
       ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=10)
             Filter: (id = 99)
       ->  Index Scan using test_t1_1000_pkey on test_t1_1000 test  (cost=0.00..7.27 rows=1 width=10)
             Index Cond: (id = 99)
    (5 rows)

    5.11
    按分区列值 删除,走分区表索引扫描
    edbtest=# explain delete from test where id=99;
                                               QUERY PLAN                                           
    -------------------------------------------------------------------------------------------------
     Delete on test  (cost=0.00..7.27 rows=2 width=6)
       ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=6)
             Filter: (id = 99)
       ->  Index Scan using test_t1_1000_pkey on test_t1_1000 test  (cost=0.00..7.27 rows=1 width=6)
             Index Cond: (id = 99)
    (5 rows)

    edbtest=#

    -----------------

    转载请著明出处:
    blog.csdn.net/beiigang
    beigang.iteye.com

  • 相关阅读:
    IntentService使用以及源码分析
    Android HandlerThread源码解析
    Android Handler消息机制源码解析
    Gradle技术之四
    Android EditText实现小数点后几位的终级方案
    Gradle系列之三 Gradle概述以及生命周期
    Gradle系列之二 Groovy对文件的操作
    Gradle系列之一 Groovy语法精讲
    Context源码分析
    用EXCLE群发outlook邮件
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3127569.html
Copyright © 2020-2023  润新知