PostgreSQL的隐藏功能

ram*_*jan 79 database postgresql rdbms postgresql-9.3

我很惊讶这还没有发布.你在Postgres知道的任何有趣的技巧?晦涩的配置选项和缩放/执行技巧特别受欢迎.

我相信我们可以在相应的MySQL线程上击败9条评论:)

tom*_*mym 75

由于postgres比MySQL更加理智,所以没有那么多"技巧"来报道;-)

手册有一些不错的性能提示.

还需要记住一些与性能相关的事情:

  • 确保打开autovacuum
  • 确保你已经完成了你的postgres.conf(有效的缓存大小,共享缓冲区,工作mem ...有很多选项可供调整).
  • 使用pgpool或pgbouncer将您的"真实"数据库连接保持在最低限度
  • 了解EXPLAIN和EXPLAIN ANALYZE的工作原理.学习阅读输出.
  • CLUSTER根据索引对磁盘上的数据进行排序.可以显着提高大型(大多数)只读表的性能.群集是一次性操作:随后更新表时,更改不会群集.

这里有一些我发现有用的东西,它们本身并不是配置或性能相关的.

要了解当前正在发生的事情:

select * from pg_stat_activity;
Run Code Online (Sandbox Code Playgroud)

搜索misc功能:

select * from pg_proc WHERE proname ~* '^pg_.*'
Run Code Online (Sandbox Code Playgroud)

查找数据库的大小:

select pg_database_size('postgres');
select pg_size_pretty(pg_database_size('postgres'));
Run Code Online (Sandbox Code Playgroud)

查找所有数据库的大小:

select datname, pg_size_pretty(pg_database_size(datname)) as size
  from pg_database;
Run Code Online (Sandbox Code Playgroud)

查找表和索引的大小:

select pg_size_pretty(pg_relation_size('public.customer'));
Run Code Online (Sandbox Code Playgroud)

或者,列出所有表和索引(可能更容易查看):

select schemaname, relname,
    pg_size_pretty(pg_relation_size(schemaname || '.' || relname)) as size
  from (select schemaname, relname, 'table' as type
          from pg_stat_user_tables
        union all
        select schemaname, relname, 'index' as type
          from pg_stat_user_indexes) x;
Run Code Online (Sandbox Code Playgroud)

哦,你可以嵌套事务,回滚部分事务++

test=# begin;
BEGIN
test=# select count(*) from customer where name='test';
 count 
-------
     0
(1 row)
test=# insert into customer (name) values ('test');
INSERT 0 1
test=# savepoint foo;
SAVEPOINT
test=# update customer set name='john';
UPDATE 3
test=# rollback to savepoint foo;
ROLLBACK
test=# commit;
COMMIT
test=# select count(*) from customer where name='test';
 count 
-------
     1
(1 row)
Run Code Online (Sandbox Code Playgroud)

  • 替换(回答,'每说','本身') (3认同)

Chr*_*heD 23

最简单的窍门,让PostgreSQL的执行好多了(除了设置和使用过程中的适当指标)只是给它更多的内存一起工作(如果你还没有这样做的话).在大多数默认安装中,shared_buffers的值太低(在我看来).你可以设置

的shared_buffers

在postgresql.conf中.将此数字除以128可获得postgres可以声明的内存量(以MB为单位)的近似值.如果你足够了,这将使postgresql飞.别忘了重启postgresql.

在Linux系统上,当postgresql不会再次启动时,您可能会达到kernel.shmmax限制.用它设置得更高

sysctl -w kernel.shmmax=xxxx
Run Code Online (Sandbox Code Playgroud)

要在引导之间保持这种状态,请在/etc/sysctl.conf中添加kernel.shmmax条目.

可以在这里找到一大堆Postgresql技巧:


Yan*_*min 17

由于INTERVAL的支持,Postgres拥有非常强大的日期处理设施.

例如:

select NOW(), NOW() + '1 hour';
              now              |           ?column?            
-------------------------------+-------------------------------
 2009-04-18 01:37:49.116614+00 | 2009-04-18 02:37:49.116614+00
(1 row)



select current_date ,(current_date +  interval '1 year')::date;
    date             |  date            
---------------------+----------------
 2014-10-17          | 2015-10-17
(1 row)
Run Code Online (Sandbox Code Playgroud)

您可以将许多字符串转换为INTERVAL类型.


ram*_*jan 15

复制

我会开始的.每当我从SQLite切换到Postgres时,我通常都会有一些非常大的数据集.关键是使用COPY FROM加载表而不是INSERTS.见文档:

http://www.postgresql.org/docs/8.1/static/sql-copy.html

以下示例使用竖线(|)作为字段分隔符将表复制到客户端:

COPY country TO STDOUT WITH DELIMITER '|';
Run Code Online (Sandbox Code Playgroud)

要将文件中的数据复制到国家/地区表格中:

COPY country FROM '/usr1/proj/bray/sql/country_data';
Run Code Online (Sandbox Code Playgroud)

另请参见此处: sqlite3中更快的批量插入?

  • 这对于csv导入也很方便. (2认同)

Qua*_*noi 12

  • 我最喜欢的是generate_series:最后一个生成虚拟行集的简洁方法.
  • 能够在LIMIT子查询的子句中使用相关值:

    SELECT  (
            SELECT  exp_word
            FROM    mytable
            OFFSET id
            LIMIT 1
            )
    FROM    othertable
    
    Run Code Online (Sandbox Code Playgroud)
  • Abitlity在自定义聚合中使用多个参数(文档未涵盖):请参阅我博客中的文章以获取示例.


Cha*_*rch 9

我真正喜欢Postgres的一个方面是列中支持的一些数据类型.例如,存在用于存储网络地址数组的列类型.这些列类型的相应函数(网络地址/数组)允许您在查询中执行大量复杂操作,您必须通过MySQL或其他数据库引擎中的代码处理结果.

  • 如果标准版本不适合您,您可以轻松创建自己的类型! (2认同)

Nic*_*ard 8

一旦你了解它们,阵列真的很酷.假设您想在页面之间存储一些超链接.您可以首先考虑创建一个像这样的表:

CREATE TABLE hyper.links (
     tail INT4,
     head INT4
);
Run Code Online (Sandbox Code Playgroud)

如果你需要索引列,并且你有200,000,000个链接行(就像维基百科会给你的那样),你会发现自己有一个巨大的表和一个巨大的索引.

但是,使用PostgreSQL,您可以使用此表格格式:

CREATE TABLE hyper.links (
     tail INT4,
     head INT4[],
     PRIMARY KEY(tail)
);
Run Code Online (Sandbox Code Playgroud)

为了得到链接的所有头,你可以发送这样的命令(从8.4开始,unexst()是标准的):

SELECT unnest(head) FROM hyper.links WHERE tail = $1;
Run Code Online (Sandbox Code Playgroud)

与第一个选项进行比较时,此查询的速度非常快(unexst()快速且索引更小).此外,您的表和索引将占用更少的RAM内存和HD空间,特别是当您的阵列太长以至于它们被压缩为Toast Table时.数组非常强大.

注意:虽然unnest()将从数组中生成行,但array_agg()会将行聚合到数组中.


小智 6

物化视图很容易设置:

CREATE VIEW my_view AS SELECT id, AVG(my_col) FROM my_table GROUP BY id;
CREATE TABLE my_matview AS SELECT * FROM my_view;
Run Code Online (Sandbox Code Playgroud)

这将创建一个新表my_matview,其中包含my_view的列和值.然后可以设置触发器或cron脚本以使数据保持最新,或者如果您是懒惰的:

TRUNCATE my_matview;
INSERT INTO my_matview SELECT * FROM my_view;
Run Code Online (Sandbox Code Playgroud)


小智 6

  • Inheritance..infact多重继承(在父子"继承"中,不是许多Web框架在使用postgres时实现的一对一关系继承).

  • PostGIS(空间扩展),一个出色的附加组件,提供全面的几何函数集并开箱即用地协调存储.广泛用于许多开源地理库(例如OpenLayers,MapServer,Mapnik等),并且明显优于MySQL的空间扩展.

  • 使用不同语言编写程序,例如C,Python,Perl等(如果您是开发人员而不是db-admin,那么您的生活将变得更容易编码).

    此外,所有过程都可以存储在外部(作为模块),并且可以在运行时通过指定的参数进行调用或导入.这样,您就可以轻松控制代码并调试代码.

  • 关于数据库中实现的所有对象(即表,约束,索引等)的庞大而全面的目录.

    我总是发现运行少量查询并获取所有元信息非常有用,例如,约束名称和已实现它们的字段,索引名称等.

    对我来说,当我必须加载新数据或在大表中进行大量更新(我会自动禁用触发器和删除索引)然后在处理完成后再次轻松地重新创建它们时,这一切都变得非常方便.写一些这些查询的人做得非常出色.

    http://www.alberton.info/postgresql_meta_info.html

  • 在一个数据库下有多个模式,如果数据库有大量表,则可以使用它,可以将模式视为类别.所有表(无论其架构如何)都可以访问父db中存在的所有其他表和函数.


小智 5

你不需要学习如何破译"解析分析"输出,还有一个工具:http://explain.depesz.com