zoukankan      html  css  js  c++  java
  • postgresql 表的 tablesample

    os:centos 7.4
    postgresql:10.4

    postgresql 的数据抽样是从 9.5版本开始提供,主要是解决从大量数据中随机获取一些数据的效率。

    ##生成数据

    $ psql
    psql (10.4)
    Type "help" for help.
    
    postgres=# create table test01(id integer, val char(1000)); 
    CREATE TABLE
    postgres=# insert into test01 values(generate_series(1,500000),repeat( chr(int4(random()*26)+65),1000));
    

    查看普通方法的执行计划

    postgres=# 	iming
    Timing is on.
    postgres=# explain analyze verbose select * from test01 order by random() limit 2;
                                                                  QUERY PLAN                                
                                  
    --------------------------------------------------------------------------------------------------------------------------------------
     Limit  (cost=44583.98..44583.98 rows=2 width=1040) (actual time=464.091..464.092 rows=2 loops=1)
       Output: id, val, (random())
       ->  Sort  (cost=44583.98..45833.97 rows=499999 width=1040) (actual time=464.090..464.090 rows=2 loops=1)
             Output: id, val, (random())
             Sort Key: (random())
             Sort Method: top-N heapsort  Memory: 31kB
             ->  Seq Scan on public.test01  (cost=0.00..39583.99 rows=499999 width=1040) (actual time=9.696..340.137 rows=500000 loops=1)
                   Output: id, val, random()
     Planning time: 0.139 ms
     Execution time: 464.113 ms
    (10 rows)
    
    Time: 613.564 ms
    

    可以看到执行计划是走的全表扫描。

    select *
    from tablename
    [ TABLESAMPLE sampling_method ( argument [, …] ) [ REPEATABLE ( seed ) ] ]

    TABLESAMPLE sampling_method ( argument [, …] ) [ REPEATABLE ( seed ) ]
    table_name之后的 TABLESAMPLE子句表示应该用指定的 sampling_method 来检索表中行的子集。这种采样优先于任何其他过滤器(例如 WHERE子句)。
    标准 PostgreSQL发布包括两种采样 方法:BERNOULLI和SYSTEM, 其他采样方法可以通过扩展安装在数据库中。

    BERNOULLI以及SYSTEM采样方法都接受 一个参数,它表示要采样的表 的分数,表示为一个 0 到 100 之间的百分数。
    这个参数可以是任意的 实数值表达式(其他的采样方法可能接受更多或者不同的 参数)。这两种方法都返回一个随机选取的该表采样,其中包含了指定 百分数的表行。

    BERNOULLI方法扫描整个表并且用指定的几率选择或者忽略行。
    SYSTEM方法会做 块层的采样,每个块都有指定的机会能被选中,被选中块中的所有行都会被返回。

    在指定较小的采样百分数时,SYSTEM 方法要比BERNOULLI方法快很多,但是前者可能 由于聚簇效应返回随机性较差的表采样。

    可选的REPEATABLE子句指定一个用于产生采样方法中随机数的种子数或表达式。种子值可以是任何非空浮点值。如果查询时表没有被更改,指定相同种子和argument值的两个查询将会选择该表相同的采样。
    但是不同的种子值通常将会产生不同的采样。如果没有给出REPEATABLE,则会基于一个系统产生的种子为每一个查询选择一个新的随机采样。注意有些扩展采样方法不接受REPEATABLE,并且将总是为每一次使用产生新的采样。

    ##tablesample system
    system抽样方式为随机抽取表的数据块上的数据,抽样级别为数据块级别。被选中的所有行都会被返回。

    postgres=# explain analyze verbose select * from test01 tablesample system(0.01);
                                                       QUERY PLAN                                                   
    ----------------------------------------------------------------------------------------------------------------
     Sample Scan on public.test01  (cost=0.00..12.50 rows=50 width=1032) (actual time=0.056..0.175 rows=45 loops=1)
       Output: id, val
       Sampling: system ('0.01'::real)
     Planning time: 0.027 ms
     Execution time: 0.189 ms
    (5 rows)
    
    Time: 0.493 ms
    

    ##tablesample bernoulli
    system抽样方式为随机抽取表的数据行数据,抽样级别为数据行级别。比 system 具有更好的随机性,但是性能要差很多。

    postgres=# explain analyze verbose select * from test01 tablesample bernoulli(0.01);
                                                         QUERY PLAN                                                     
    --------------------------------------------------------------------------------------------------------------------
     Sample Scan on public.test01  (cost=0.00..33334.50 rows=50 width=1032) (actual time=1.688..80.150 rows=47 loops=1)
       Output: id, val
       Sampling: bernoulli ('0.01'::real)
     Planning time: 0.029 ms
     Execution time: 80.173 ms
    (5 rows)
    
    Time: 80.461 ms
    

    可以看出 bernoulli 比 system 的性能要低很多,耗时大概为160倍。

    参考:
    http://postgres.cn/docs/10/sql-select.html

  • 相关阅读:
    springcloud随便写点
    简单的数组排序
    简单wait(),notify()方法
    热词
    mysql日期函数
    springboot和jsp,以及引入jquery
    用户,权限,角色的关系
    通过字节码获取到的方法
    数据库并发事物
    在spring的业务层获取request,response
  • 原文地址:https://www.cnblogs.com/ctypyb2002/p/9792895.html
Copyright © 2011-2022 走看看