PostgreSQL 的隐藏特性

发布于 2024-07-17 10:24:12 字数 1436 浏览 16 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

羅雙樹 2024-07-24 10:24:12

由于 postgres 比 MySQL 更理智,因此没有那么多“技巧”需要报告;-)

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

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

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

以下是我发现的一些有用的东西,它们本身与配置或性能无关。

要查看当前发生的情况:

select * from pg_stat_activity;

搜索杂项函数:

select * from pg_proc WHERE proname ~* '^pg_.*'

查找数据库的大小:

select pg_database_size('postgres');
select pg_size_pretty(pg_database_size('postgres'));

查找所有数据库的大小:

select datname, pg_size_pretty(pg_database_size(datname)) as size
  from pg_database;

查找表和索引的大小:

select pg_size_pretty(pg_relation_size('public.customer'));

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

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;

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

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)

Since postgres is a lot more sane than MySQL, there are not that many "tricks" to report on ;-)

The manual has some nice performance tips.

A few other performance related things to keep in mind:

  • Make sure autovacuum is turned on
  • Make sure you've gone through your postgres.conf (effective cache size, shared buffers, work mem ... lots of options there to tune).
  • Use pgpool or pgbouncer to keep your "real" database connections to a minimum
  • Learn how EXPLAIN and EXPLAIN ANALYZE works. Learn to read the output.
  • CLUSTER sorts data on disk according to an index. Can dramatically improve performance of large (mostly) read-only tables. Clustering is a one-time operation: when the table is subsequently updated, the changes are not clustered.

Here's a few things I've found useful that aren't config or performance related per se.

To see what's currently happening:

select * from pg_stat_activity;

Search misc functions:

select * from pg_proc WHERE proname ~* '^pg_.*'

Find size of database:

select pg_database_size('postgres');
select pg_size_pretty(pg_database_size('postgres'));

Find size of all databases:

select datname, pg_size_pretty(pg_database_size(datname)) as size
  from pg_database;

Find size of tables and indexes:

select pg_size_pretty(pg_relation_size('public.customer'));

Or, to list all tables and indexes (probably easier to make a view of this):

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;

Oh, and you can nest transactions, rollback partial transactions++

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)
过去的过去 2024-07-24 10:24:12

让 postgresql 执行得更好的最简单技巧(当然除了设置和使用正确的索引之外)就是给它更多的 RAM 来使用(如果你还没有这样做的话)。 在大多数默认安装中,shared_buffers 的值太低(在我看来)。 您可以设置

共享缓冲区

postgresql.conf 中的 。 将此数字除以 128 即可得到 postgres 可以占用的内存量(以 MB 为单位)的近似值。 如果你足够多的话,这将使 postgresql 飞起来。 不要忘记重新启动 postgresql。

在 Linux 系统上,当 postgresql 无法再次启动时,您可能已经达到了 kernel.shmmax 限制。 将其设置得更高 要

sysctl -w kernel.shmmax=xxxx

使其在引导之间持续存在,请将 kernel.shmmax 条目添加到 /etc/sysctl.conf。

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

The easiest trick to let postgresql perform a lot better (apart from setting and using proper indexes of course) is just to give it more RAM to work with (if you have not done so already). On most default installations the value for shared_buffers is way too low (in my opinion). You can set

shared_buffers

in postgresql.conf. Divide this number by 128 to get an approximation of the amount of memory (in MB) postgres can claim. If you up it enough this will make postgresql fly. Don't forget to restart postgresql.

On Linux systems, when postgresql won't start again you will probably have hit the kernel.shmmax limit. Set it higher with

sysctl -w kernel.shmmax=xxxx

To make this persist between boots, add a kernel.shmmax entry to /etc/sysctl.conf.

A whole bunch of Postgresql tricks can be found here:

你げ笑在眉眼 2024-07-24 10:24:12

由于 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)

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

Postgres has a very powerful datetime handling facility thanks to its INTERVAL support.

For example:

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)

You can cast many strings to an INTERVAL type.

烟凡古楼 2024-07-24 10:24:12

复制

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

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

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

COPY country TO STDOUT WITH DELIMITER '|';

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

COPY country FROM '/usr1/proj/bray/sql/country_data';

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

COPY

I'll start. Whenever I switch to Postgres from SQLite, I usually have some really big datasets. The key is to load your tables with COPY FROM rather than doing INSERTS. See documentation:

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

The following example copies a table to the client using the vertical bar (|) as the field delimiter:

COPY country TO STDOUT WITH DELIMITER '|';

To copy data from a file into the country table:

COPY country FROM '/usr1/proj/bray/sql/country_data';

See also here:
Faster bulk inserts in sqlite3?

赠意 2024-07-24 10:24:12
  • 到目前为止,我最喜欢的是 generate_series:最后是一种生成虚拟行集的干净方法。
  • 能够在子查询的LIMIT子句中使用相关值:

    <前><代码>选择(
    选择exp_word
    来自我的表
    偏移量 ID
    限制1

    来自其他表

  • 能够在自定义聚合中使用多个参数(文档未涵盖):请参阅 我博客中的文章
  • My by far favorite is generate_series: at last a clean way to generate dummy rowsets.
  • Ability to use a correlated value in a LIMIT clause of a subquery:

    SELECT  (
            SELECT  exp_word
            FROM    mytable
            OFFSET id
            LIMIT 1
            )
    FROM    othertable
    
  • Abitlity to use multiple parameters in custom aggregates (not covered by the documentation): see the article in my blog for an example.
东走西顾 2024-07-24 10:24:12

我真正喜欢 Postgres 的事情之一是列中支持的一些数据类型。 例如,有一些列类型用于存储网络地址 和 数组。 相应的函数 (网络地址 / Arrays) 对于这些列类型,您可以在查询中执行许多复杂的操作,您必须通过 MySQL 或其他数据库引擎中的代码处理结果。

One of the things I really like about Postgres is some of the data types supported in columns. For example, there are column types made for storing Network Addresses and Arrays. The corresponding functions (Network Addresses / Arrays) for these column types let you do a lot of complex operations inside queries that you'd have to do by processing results through code in MySQL or other database engines.

沐歌 2024-07-24 10:24:12

一旦你了解了数组,它们就会变得非常酷。
假设您想在页面之间存储一些超链接。 您可能首先考虑创建一个类似这样的表:

CREATE TABLE hyper.links (
     tail INT4,
     head INT4
);

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

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

CREATE TABLE hyper.links (
     tail INT4,
     head INT4[],
     PRIMARY KEY(tail)
);

要获取链接的所有头,您可以发送如下命令(unnest() 自 8.4 起成为标准):

SELECT unnest(head) FROM hyper.links WHERE tail = $1;

与第一个选项相比,此查询速度惊人地快(unnest() 速度很快,而且索引要小得多)。 此外,您的表和索引将占用更少的 RAM 内存和硬盘空间,尤其是当您的数组太长以至于被压缩到 Toast 表时。 数组确实很强大。

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

Arrays are really cool once you get to know 'em.
Lets say you would like to store some hyper links between pages. You might start by thinking about creating a Table kinda like this:

CREATE TABLE hyper.links (
     tail INT4,
     head INT4
);

If you needed to index the tail column, and you had, say 200,000,000 links-rows (like wikipedia would give you), you would find yourself with a huge Table and a huge Index.

However, with PostgreSQL, you could use this Table format instead:

CREATE TABLE hyper.links (
     tail INT4,
     head INT4[],
     PRIMARY KEY(tail)
);

To get all heads for a link you could send a command like this (unnest() is standard since 8.4):

SELECT unnest(head) FROM hyper.links WHERE tail = $1;

This query is surprisingly fast when it is compared with the first option (unnest() is fast and the Index is way way smaller). Furthermore, your Table and Index will take up much less RAM-memory and HD-space, especially when your Arrays are so long that they are compressed to a Toast Table. Arrays are really powerful.

Note: while unnest() will generate rows out of an Array, array_agg() will aggregate rows into an Array.

我也只是我 2024-07-24 10:24:12

物化视图非常容易设置:

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;

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

TRUNCATE my_matview;
INSERT INTO my_matview SELECT * FROM my_view;

Materialized Views are pretty easy to setup:

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;

That creates a new table, my_matview, with the columns and values of my_view. Triggers or a cron script can then be setup to keep the data up to date, or if you're lazy:

TRUNCATE my_matview;
INSERT INTO my_matview SELECT * FROM my_view;
拍不死你 2024-07-24 10:24:12
  • Inheritance..infact 多重继承(如父子“继承”,而不是许多 Web 框架在使用 postgres 时实现的 1 对 1 关系继承)。

  • PostGIS(空间扩展),一个出色的附加组件,提供全面的几何函数集和开箱即用的坐标存储。 广泛用于许多开源地理库(例如 OpenLayers、MapServer、Mapnik 等),并且绝对比 MySQL 的空间扩展更好。

  • 用不同的语言编写程序,例如 C、Python、Perl 等(如果您是开发人员而不是数据库管理员,那么您的编码生活会更轻松)。

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

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

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

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

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

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

  • Inheritance..infact Multiple Inheritance (as in parent-child "inheritance" not 1-to-1 relation inheritance which many web frameworks implement when working with postgres).

  • PostGIS (spatial extension), a wonderful add-on that offers comprehensive set of geometry functions and coordinates storage out of the box. Widely used in many open-source geo libs (e.g. OpenLayers,MapServer,Mapnik etc) and definitely way better than MySQL's spatial extensions.

  • Writing procedures in different languages e.g. C, Python,Perl etc (makes your life easir to code if you're a developer and not a db-admin).

    Also all procedures can be stored externally (as modules) and can be called or imported at runtime by specified arguments. That way you can source control the code and debug the code easily.

  • A huge and comprehensive catalogue on all objects implemented in your database (i.e. tables,constraints,indexes,etc).

    I always find it immensely helpful to run few queries and get all meta info e.g. ,constraint names and fields on which they have been implemented on, index names etc.

    For me it all becomes extremely handy when I have to load new data or do massive updates in big tables (I would automatically disable triggers and drop indexes) and then recreate them again easily after processing has finished. Someone did an excellent job of writing handful of these queries.

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

  • Multiple schemas under one database, you can use it if your database has large number of tables, you can think of schemas as categories. All tables (regardless of it's schema) have access to all other tables and functions present in parent db.

棒棒糖 2024-07-24 10:24:12

您不需要学习如何破译“解释分析”输出,有一个工具:http://explain.depesz。 com

You don't need to learn how to decipher "explain analyze" output, there is a tool: http://explain.depesz.com

柠檬色的秋千 2024-07-24 10:24:12
select pg_size_pretty(200 * 1024)
select pg_size_pretty(200 * 1024)
小矜持 2024-07-24 10:24:12

pgcrypto:比许多编程语言的加密模块提供的加密功能更多,所有这些都可以直接从数据库访问。 它使加密技术变得非常容易“Just Get Right”。

pgcrypto: more cryptographic functions than many programming languages' crypto modules provide, all accessible direct from the database. It makes cryptographic stuff incredibly easy to Just Get Right.

没有你我更好 2024-07-24 10:24:12

一次性数据/全局变量的内存存储

您可以创建一个位于 RAM 中的表空间,并在该表空间中创建表(在 9.1 中可能未记录)来存储一次性数据/全局变量您想要跨会话共享。

http://杂志。 redhat.com/2007/12/12/tip-from-an-rhce-memory-storage-on-postgresql/

咨询锁

这些记录在手册的一个不起眼的区域中:

http://www.postgresql.org/docs/9.0/interactive/functions -admin.html

它有时比获取大量行级锁更快,并且它们可用于解决未实现 FOR UPDATE 的情况(例如递归 CTE 查询)。

Memory storage for throw-away data/global variables

You can create a tablespace that lives in the RAM, and tables (possibly unlogged, in 9.1) in that tablespace to store throw-away data/global variables that you'd like to share across sessions.

http://magazine.redhat.com/2007/12/12/tip-from-an-rhce-memory-storage-on-postgresql/

Advisory locks

These are documented in an obscure area of the manual:

http://www.postgresql.org/docs/9.0/interactive/functions-admin.html

It's occasionally faster than acquiring multitudes of row-level locks, and they can be used to work around cases where FOR UPDATE isn't implemented (such as recursive CTE queries).

一个人的夜不怕黑 2024-07-24 10:24:12

这是我最喜欢的鲜为人知的功能列表。

事务性 DDL

几乎每个 SQL 语句在 Postgres 中都是事务性的。 如果关闭自动提交,则可能发生以下情况:

drop table customer_orders;
rollback;
select *
from customer_orders;

范围类型和排除约束

据我所知,Postgres 是唯一允许您创建检查两个范围是否重叠的约束的 RDBMS。 一个示例是包含具有“有效期开始”和“有效期至”日期的产品价格的表:

create table product_price
(
   price_id      serial        not null primary key,
   product_id    integer       not null references products,
   price         numeric(16,4) not null,
   valid_during  daterange not null
);

NoSQL 功能

hstore 扩展提供了灵活且非常快速的键/值存储,可在零件时使用数据库的结构需要“无模式”。 JSON 是另一种以无模式方式存储数据的选项,并且

insert into product_price 
  (product_id, price, valid_during)
values 
  (1, 100.0, '[2013-01-01,2014-01-01)'),
  (1,  90.0, '[2014-01-01,)');


-- querying is simply and can use an index on the valid_during column
select price
from product_price
where product_id = 42
  and valid_during @> date '2014-10-17';

在具有 700.000 行的表上执行上述操作的计划:

Index Scan using check_price_range on public.product_price  (cost=0.29..3.29 rows=1 width=6) (actual time=0.605..0.728 rows=1 loops=1)
  Output: price
  Index Cond: ((product_price.valid_during @> '2014-10-17'::date) AND (product_price.product_id = 42))
  Buffers: shared hit=17
Total runtime: 0.772 ms

为了避免插入有效范围重叠的行,可以定义一个简单(且有效)的唯一约束:

alter table product_price
  add constraint check_price_range 
  exclude using gist (product_id with =, valid_during with &&)

Infinity

而不是需要一个遥远的“真实”日期 Postgres 可以将日期与无穷大进行比较。 例如,当不使用日期范围时,您可以执行以下

insert into product_price 
  (product_id, price, valid_from, valid_until)
values 
  (1,  90.0, date '2014-01-01', date 'infinity');

可写公共表表达式

您可以在单个语句中删除、插入和选择:

with old_orders as (
   delete from orders
   where order_date < current_date - interval '10' year
   returning *
), archived_rows as (
   insert into archived_orders 
   select * 
   from old_orders
   returning *
)
select *
from archived_rows;

上面将删除所有超过 10 年的订单,将它们移动到 archived_orders 表,然后显示已移动的行。

This is my favorites list of lesser know features.

Transactional DDL

Nearly every SQL statement is transactional in Postgres. If you turn off autocommit the following is possible:

drop table customer_orders;
rollback;
select *
from customer_orders;

Range types and exclusion constraint

To my knowledge Postgres is the only RDBMS that lets you create a constraint that checks if two ranges overlap. An example is a table that contains product prices with a "valid from" and "valid until" date:

create table product_price
(
   price_id      serial        not null primary key,
   product_id    integer       not null references products,
   price         numeric(16,4) not null,
   valid_during  daterange not null
);

NoSQL features

The hstore extension offers a flexible and very fast key/value store that can be used when parts of the database need to be "schema-less". JSON is another option to store data in a schema-less fashion and

insert into product_price 
  (product_id, price, valid_during)
values 
  (1, 100.0, '[2013-01-01,2014-01-01)'),
  (1,  90.0, '[2014-01-01,)');


-- querying is simply and can use an index on the valid_during column
select price
from product_price
where product_id = 42
  and valid_during @> date '2014-10-17';

The execution plan for the above on a table with 700.000 rows:

Index Scan using check_price_range on public.product_price  (cost=0.29..3.29 rows=1 width=6) (actual time=0.605..0.728 rows=1 loops=1)
  Output: price
  Index Cond: ((product_price.valid_during @> '2014-10-17'::date) AND (product_price.product_id = 42))
  Buffers: shared hit=17
Total runtime: 0.772 ms

To avoid inserting rows with overlapping validity ranges a simple (and efficient) unique constraint can be defined:

alter table product_price
  add constraint check_price_range 
  exclude using gist (product_id with =, valid_during with &&)

Infinity

Instead of requiring a "real" date far in the future Postgres can compare dates to infinity. E.g. when not using a date range you can do the following

insert into product_price 
  (product_id, price, valid_from, valid_until)
values 
  (1,  90.0, date '2014-01-01', date 'infinity');

Writeable common table expressions

You can delete, insert and select in a single statement:

with old_orders as (
   delete from orders
   where order_date < current_date - interval '10' year
   returning *
), archived_rows as (
   insert into archived_orders 
   select * 
   from old_orders
   returning *
)
select *
from archived_rows;

The above will delete all orders older than 10 years, move them to the archived_orders table and then display the rows that were moved.

节枝 2024-07-24 10:24:12

1.) 当您需要附加通知进行查询时,可以使用嵌套注释

SELECT /* my comments, that I would to see in PostgreSQL log */
       a, b, c
   FROM mytab;

2.) 从所有文本中删除尾随空格<数据库中的 /code> 和 varchar 字段。

do $
declare
    selectrow record;
begin
for selectrow in
select 
       'UPDATE '||c.table_name||' SET '||c.COLUMN_NAME||'=TRIM('||c.COLUMN_NAME||')  WHERE '||c.COLUMN_NAME||' ILIKE ''% '' ' as script
from (
       select 
          table_name,COLUMN_NAME
       from 
          INFORMATION_SCHEMA.COLUMNS 
       where 
          table_name LIKE 'tbl%'  and (data_type='text' or data_type='character varying' )
     ) c
loop
execute selectrow.script;
end loop;
end;
$;

3.) 我们可以使用窗口函数非常有效地删除重复行:

DELETE FROM tab 
  WHERE id IN (SELECT id 
                  FROM (SELECT row_number() OVER (PARTITION BY column_with_duplicate_values), id 
                           FROM tab) x 
                 WHERE x.row_number > 1);

一些 PostgreSQL 的优化版本(带有 ctid):

DELETE FROM tab 
  WHERE ctid = ANY(ARRAY(SELECT ctid 
                  FROM (SELECT row_number() OVER (PARTITION BY column_with_duplicate_values), ctid 
                           FROM tab) x 
                 WHERE x.row_number > 1));

4.) 当我们需要识别服务器的状态时,我们可以使用一个函数:

SELECT pg_is_in_recovery();

5.) 获取函数的DDL命令。

select pg_get_functiondef((select oid from pg_proc where proname = 'f1'));

6.) 安全地更改PostgreSQL中的列数据类型

create table test(id varchar );
insert into test values('1');
insert into test values('11');
insert into test values('12');

select * from test
--Result--
id
character varying
--------------------------
1
11
12

从上表可以看出我已经使用了数据类型 - 'id' 的'字符变化'
柱子。 但这是一个错误,因为我总是给出整数作为 id。 所以这里使用 varchar 是
不好的做法。 因此,我们尝试将列类型更改为整数。

ALTER TABLE test ALTER COLUMN id TYPE integer;

但它返回:

错误:列“id”无法自动转换为整数 SQL
state: 42804 提示:指定一个 USING 表达式来执行
转换

这意味着我们不能简单地更改数据类型,因为数据已经存在于列中。 由于数据的类型为“字符变化”,postgres 不能期望它是整数,尽管我们只输入了整数。 所以现在,正如 postgres 建议的那样,我们可以使用“USING”表达式将数据转换为整数。

ALTER TABLE test ALTER COLUMN id  TYPE integer USING (id ::integer);

有用。

7.) 了解谁连接到数据库
这或多或少是一个监控命令。 了解哪个用户连接到哪个数据库
包括其 IP 和端口,使用以下 SQL:

SELECT datname,usename,client_addr,client_port FROM pg_stat_activity ;

8.) 重新加载 PostgreSQL 配置文件而不重新启动服务器

PostgreSQL 配置参数位于 postgresql.conf 和 pg_hba.conf 等特殊文件中。 通常,您可能需要更改这些参数。 但为了让某些参数生效我们常常需要重新加载配置文件。 当然,重启服务器就可以了。 但在生产环境中,不建议重新启动数据库,因为数据库已被数千人使用,只是为了设置一些参数。 在这种情况下,我们可以使用以下函数来重新加载配置文件,而无需重新启动服务器:

select pg_reload_conf();

记住,这不适用于所有参数,某些参数
更改需要完全重新启动服务器才能生效。

9.) 获取当前数据库集群的数据目录路径

在一个系统中,可能会设置多个PostgreSQL实例(集群),一般情况下,会分布在不同的地方。端口等。 在这种情况下,查找哪个实例使用哪个目录(物理存储目录)是一项繁重的任务。 在这种情况下,我们可以在我们感兴趣的集群中的任何数据库中使用以下命令来获取目录路径:

SHOW data_directory;

可以使用相同的功能来更改集群的数据目录,但它需要服务器重新启动:

SET data_directory to new_directory_path;

10.) 查找 CHAR 是否为 DATE

create or replace function is_date(s varchar) returns boolean as $
begin
  perform s::date;
  return true;
exception when others then
  return false;
end;
$ language plpgsql;

用法:以下内容将返回 True

select is_date('12-12-2014')
select is_date('12/12/2014')
select is_date('20141212')
select is_date('2014.12.12')
select is_date('2014,12,12')

11.) 更改 PostgreSQL 中的所有者< /em>

REASSIGN OWNED BY sa  TO postgres;

12.) PGADMIN PLPGSQL DEBUGGER

解释得很好 此处

1.) When you need append notice to query, you can use nested comment

SELECT /* my comments, that I would to see in PostgreSQL log */
       a, b, c
   FROM mytab;

2.) Remove Trailing spaces from all the text and varchar field in a database.

do $
declare
    selectrow record;
begin
for selectrow in
select 
       'UPDATE '||c.table_name||' SET '||c.COLUMN_NAME||'=TRIM('||c.COLUMN_NAME||')  WHERE '||c.COLUMN_NAME||' ILIKE ''% '' ' as script
from (
       select 
          table_name,COLUMN_NAME
       from 
          INFORMATION_SCHEMA.COLUMNS 
       where 
          table_name LIKE 'tbl%'  and (data_type='text' or data_type='character varying' )
     ) c
loop
execute selectrow.script;
end loop;
end;
$;

3.) We can use a window function for very effective removing of duplicate rows:

DELETE FROM tab 
  WHERE id IN (SELECT id 
                  FROM (SELECT row_number() OVER (PARTITION BY column_with_duplicate_values), id 
                           FROM tab) x 
                 WHERE x.row_number > 1);

Some PostgreSQL's optimized version (with ctid):

DELETE FROM tab 
  WHERE ctid = ANY(ARRAY(SELECT ctid 
                  FROM (SELECT row_number() OVER (PARTITION BY column_with_duplicate_values), ctid 
                           FROM tab) x 
                 WHERE x.row_number > 1));

4.) When we need to identify server's state, then we can use a function:

SELECT pg_is_in_recovery();

5.) Get functions's DDL command.

select pg_get_functiondef((select oid from pg_proc where proname = 'f1'));

6.) Safely changing column data type in PostgreSQL

create table test(id varchar );
insert into test values('1');
insert into test values('11');
insert into test values('12');

select * from test
--Result--
id
character varying
--------------------------
1
11
12

You can see from the above table that I have used the data type – ‘character varying’ for ‘id’
column. But it was a mistake, because I am always giving integers as id. So using varchar here is a
bad practice. So let’s try to change the column type to integer.

ALTER TABLE test ALTER COLUMN id TYPE integer;

But it returns:

ERROR: column “id” cannot be cast automatically to type integer SQL
state: 42804 Hint: Specify a USING expression to perform the
conversion

That means we can’t simply change the data type because data is already there in the column. Since the data is of type ‘character varying’ postgres cant expect it as integer though we entered integers only. So now, as postgres suggested we can use the ‘USING’ expression to cast our data into integers.

ALTER TABLE test ALTER COLUMN id  TYPE integer USING (id ::integer);

It Works.

7.) Know who is connected to the Database
This is more or less a monitoring command. To know which user connected to which database
including their IP and Port use the following SQL:

SELECT datname,usename,client_addr,client_port FROM pg_stat_activity ;

8.) Reloading PostgreSQL Configuration files without Restarting Server

PostgreSQL configuration parameters are located in special files like postgresql.conf and pg_hba.conf. Often, you may need to change these parameters. But for some parameters to take effect we often need to reload the configuration file. Of course, restarting server will do it. But in a production environment it is not preferred to restarting the database, which is being used by thousands, just for setting some parameters. In such situations, we can reload the configuration files without restarting the server by using the following function:

select pg_reload_conf();

Remember, this wont work for all the parameters, some parameter
changes need a full restart of the server to be take in effect.

9.) Getting the data directory path of the current Database cluster

It is possible that in a system, multiple instances(cluster) of PostgreSQL is set up, generally, in different ports or so. In such cases, finding which directory(physical storage directory) is used by which instance is a hectic task. In such cases, we can use the following command in any database in the cluster of our interest to get the directory path:

SHOW data_directory;

The same function can be used to change the data directory of the cluster, but it requires a server restarts:

SET data_directory to new_directory_path;

10.) Find a CHAR is DATE or not

create or replace function is_date(s varchar) returns boolean as $
begin
  perform s::date;
  return true;
exception when others then
  return false;
end;
$ language plpgsql;

Usage: the following will return True

select is_date('12-12-2014')
select is_date('12/12/2014')
select is_date('20141212')
select is_date('2014.12.12')
select is_date('2014,12,12')

11.) Change the owner in PostgreSQL

REASSIGN OWNED BY sa  TO postgres;

12.) PGADMIN PLPGSQL DEBUGGER

Well explained here

能怎样 2024-07-24 10:24:12

重命名旧数据库比mysql更方便。 只需使用以下命令:

ALTER DATABASE name RENAME TO new_name

It's convenient to rename an old database rather than mysql can do. Just using the following command:

ALTER DATABASE name RENAME TO new_name
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文