Skip to content

psql 输出格式(\pset) ​

在《psql 入门》里我们只把 psql 当成「敲 SQL 的地方」,它默认的表格输出已经足够好用。但当你开始用 psql 做日常巡检、脚本化取数、生成报表、把查询结果喂给下游程序时,「默认表格」就会显得不够用:列太宽被压缩、NULL 显示为空白看不清、想直接产出 CSV 或 HTML 却不知道从哪下手。\pset 就是解决这一切的钥匙——它是 psql 内置的「输出格式化控制台」,几乎决定了每一次查询结果最终长什么样、去了哪里。

\pset 的能力覆盖四个层面:格式(aligned、csv、html 等十来种输出格式)、外观(边框、线型、分隔符、NULL 占位、是否显示行数统计)、布局(普通表格还是纵向扩展显示、分页器何时介入)与去向(输出到终端、文件还是管道)。它既可以通过 \pset 选项 值 精确设置,也有 \x、\H、\a、\t、\o 这类快捷元命令做一键切换。理解了这一页,你会把 psql 从「交互式终端」升级成「可编程的报表引擎」——后面几页的变量、事务与 \copy,也都建立在这个基础上。

需要提前说明的是:\pset 改变的是 psql 客户端的展示行为,它不改变服务器返回的数据本身。因此它对性能没有影响、对数据没有副作用,你可以放心地在任何会话里反复试验。

前置知识

建议先阅读:pg_upgrade 升级

基础概念 ​

psql 处理查询结果的流程可以概括为一条「三段式流水线」:

text
SQL 查询 ──► 服务器返回结果集 ──► psql 格式化层(\pset 状态) ──► 输出目的地
                                                    │
                                    format / border / expanded / null / pager …
                                                    │
                                        stdout / \o 文件 / 管道 / \g file
  • 格式化层由一组 \pset 状态项构成。每个状态项都有默认值,会话内可以随时修改,且只影响本会话——你在 psql 里设置的格式不会影响其他用户,也不会写进数据库。
  • 输出目的地默认是标准输出(终端),可以通过 \o 文件 或 \g 文件 重定向,也可以用 \o | 命令 直接送进管道。
  • 快捷元命令是 \pset 的别名或组合键,例如 \x 等价于切换 expanded,\t 等价于切换 tuples_only。
状态项快捷命令作用
format\a(aligned/unaligned 切换)、\H(HTML 切换)选择输出格式
border—表格边框数量
expanded\x纵向(每行一块)显示
linestyle—边框线型:ascii / old-ascii / unicode
null—NULL 值显示为什么字符串
fieldsep / recordsep\f(fieldsep)列分隔符 / 行分隔符
footer—是否显示 (n rows) 统计行
tuples_only\t只输出数据行,省去表头等装饰
pager—何时调用分页器
numericlocale—是否按本地化显示千分位
tableattr\THTML 输出时 <table> 标签的属性
title\C表格标题(HTML/某些格式下显示)
columns—wrapped 格式的目标宽度,并影响分页判断

\pset 与 COPY 的边界 ​

初学者常把 \pset format csv 与 \copy 混为一谈,这里先把边界划清:

  • \pset format csv(配合 \o 或 \g)是 psql 把查询结果「打印」成 CSV——它走的是结果集格式化层,数据先完整地经过 psql。
  • \copy 是 数据搬运命令——它利用服务器的 COPY 协议把数据流式地送进或送出文件,不经过格式化层,速度远快于「打印」。

导出少量结果给人看或给程序用,用 \pset 足够;导出大批量数据(几万行以上),用 \copy。两者的组合拳在后面《psql \copy 数据导入导出》一页详细展开。

输出流的三种消费方 ​

\pset 调什么参数,取决于结果最终给谁看。把消费方分成三类,设置策略一目了然:

消费方特征推荐设置
人(交互终端)需要可读性、容错性expanded auto + linestyle unicode + null '[NULL]' + pager
程序(脚本/管道)需要稳定契约、可解析unaligned 或 csv + tuples_only on + footer off
文件/报表(归档交付)需要自描述、可交付csv 或 html + title + header,配 \o

「人」的设置放 .psqlrc;「程序」的设置写死在脚本里(且 -X 屏蔽 .psqlrc);「文件/报表」的设置按交付物要求在脚本中显式切换。三套设置相互独立,是一条 psql 会话里随时可切换的「输出人格」——切换成本只有一条 \pset,这正是把状态机设计成会话级的好处。

语法与用法 ​

\pset 的通用语法是:

sql
\pset [ option [ value ] ]
  • 省略 option:列出当前所有格式化设置;
  • 省略 value:对布尔型选项做取反切换(例如 \pset expanded 在开/关之间切换),对枚举型选项则循环切换或报错;
  • 传入 value:精确设置。布尔值接受 on/off/true/false/1/0。
sql
-- 查看当前全部设置
\pset

-- 设置格式为 CSV
\pset format csv

-- 扩展显示自动模式(列太多放不下时自动纵向展示)
\pset expanded auto

-- NULL 显示为 <NULL>
\pset null '<NULL>'

与 \pset 对应的快捷元命令一览:

sql
\a            -- 在 aligned 与 unaligned 之间切换
\H            -- 在当前输出格式与 HTML 之间切换
\t            -- 切换 tuples_only(只显示数据行)
\x            -- 切换 expanded 显示
\f '|'        -- 设置 unaligned 格式的字段分隔符
\C '报表标题'  -- 设置表格标题(第三个 C 大写)
\T 'class=xl' -- 设置 HTML <table> 标签属性
\o 'out.txt'  -- 后续输出重定向到文件;不带参数则恢复终端

输出重定向的两条路径:

sql
-- 路径一:\g file —— 只把「当前缓冲区里这条查询」的结果写入文件,一次性
SELECT now() \g /tmp/now.txt

-- 路径二:\o file —— 从现在起「所有」输出都进入文件,直到再次执行 \o
\o /tmp/session.txt
SELECT version();
SELECT now();
\o

watch 定时重复执行当前查询缓冲区:

sql
SELECT pid, wait_event_type, query FROM pg_stat_activity WHERE state <> 'idle' \watch 5

详细说明 ​

格式家族:从 aligned 到 asciidoc ​

\pset format 的官方取值包括 aligned、unaligned、wrapped、csv、html、asciidoc、latex、latex-longtable、troff-ms。同一个结果集在不同格式下的样子差异巨大:

sql
CREATE TABLE demo (id int, name text, val numeric);
INSERT INTO demo VALUES (1, 'alpha', 1234.5), (2, NULL, 7.25);

aligned(默认)——人类可读的对齐表格:

text
 id | name  |  val
----+-------+--------
  1 | alpha | 1234.5
  2 |       |   7.25
(2 rows)

unaligned——每行一条记录,用字段分隔符(默认 |)连接,行内不换行,最贴近「原始数据流」,常用于脚本:

text
1|alpha|1234.5
2||7.25

wrapped——在 aligned 基础上,超宽的列会折行显示,配合 columns 指定目标宽度,适合查看超长的 JSON、SQL 或日志列:

text
 id |   name   |  val
----+----------+--------
  1 | alpha    | 1234.5
  2 |          |   7.25

csv——标准 CSV 输出,含引号转义处理,与 psql --csv 启动选项等价:

text
id,name,val
1,alpha,1234.5
2,,

html——完整的 HTML 片段,配合 \o 可以直接产出可浏览的报表页:

html
<table border="1">
  <tr>
    <th align="right">id</th>
    <th align="left">name</th>
    ...

asciidoc / latex / latex-longtable / troff-ms——面向文档排版工具链的标记语言输出,写 AsciiDoc 文档、LaTeX 论文或 troff 手册时可以直接嵌入。

关于 json 格式

不少资料(包括一些旧版教程)提到 \pset format json,但截至目前的官方文档,\pset format 并未收录 json 这一取值,请以你所使用版本的官方文档为准。想在 psql 里获得 JSON 输出,可靠的做法是让 SQL 自己负责序列化:

sql
SELECT json_agg(t) FROM (SELECT id, name, val FROM demo) AS t;
SELECT row_to_json(t) FROM demo AS t LIMIT 1;

边框、线型与列宽 ​

border 控制边框的丰富程度,数值越大边框越多:

  • border 0:无边框(aligned 下连列间分隔线都消失);
  • border 1:默认值,仅内部分隔线;
  • border 2:内部 + 外部边框。
sql
\pset border 2
SELECT * FROM demo;
text
+----+-------+--------+
| id | name  |  val   |
+----+-------+--------+
|  1 | alpha | 1234.5 |
|  2 |       |   7.25 |
+----+-------+--------+

linestyle 决定画线用的字符,三个取值各有味道:

取值效果场景
ascii纯 ASCII 字符(+、-、|)默认,兼容性最好
old-ascii旧版风格,扩展模式下用 : 与 ; 分隔兼容老脚本
unicode┌─┬┐ │ 等框线字符终端字体支持时更美观
sql
\pset linestyle unicode
\pset border 1
text
┌────┬───────┬────────┐
│ id │ name  │  val   │
├────┼───────┼────────┤
│  1 │ alpha │ 1234.5 │
│  2 │ ∅     │   7.25 │
└────┴───────┴────────┘

columns 设置 wrapped 格式的目标宽度,同时参与「结果会不会超过终端宽度、要不要唤起 pager」的判断。不设置时 psql 用 COLUMNS 环境变量或查询终端获得宽度;在无终端的脚本环境里,宽度判断会退化为「不分页」。

扩展显示 \x 与 expanded auto ​

默认的 aligned 表格是「一行一记录、一列一竖条」。当表很宽(例如 pg_stat_activity 有 30 多列)时,每个单元格会被压到几个字符宽,完全没法读。expanded 把布局翻转成「一行记录占一块,一行一个字段」:

sql
\pset expanded on
SELECT * FROM demo WHERE id = 1;
text
-[ RECORD 1 ]------
id   | 1
name | alpha
val  | 1234.5

expanded 有三态:on、off、auto。auto 是最值得推荐的日常设置——列少时保持表格,列多放不下时自动转纵向,两头兼顾:

sql
\pset expanded auto

快捷命令 \x 等价于对 expanded 做开关切换;\x auto、\x on、\x off 也都合法。

数据库里的 NULL 与空字符串是两回事,但默认输出里两者都是空白,肉眼根本分不开。null 选项给 NULL 一个专属记号:

sql
\pset null '[NULL]'
SELECT * FROM demo;
text
 id | name  |  val
----+--------+--------
  1 | alpha  | 1234.5
  2 | [NULL] |   7.25
(2 rows)

tuples_only(快捷键 \t)关掉表头、行数统计等所有「装饰」,只留纯数据行——写脚本时与 unaligned 搭配堪称黄金组合:

sql
\pset tuples_only on
\pset format unaligned
SELECT id, name FROM demo ORDER BY id;
text
1|alpha
2|

footer 单独控制 (n rows) 这一行。生成 CSV/报告时通常关掉它,避免最后一行混入统计信息:

sql
\pset footer off

分隔符定制:fieldsep 与 recordsep ​

fieldsep 只对 unaligned 格式生效,默认是 |。导出制表符分隔(TSV,Excel 可直接粘贴)或分号分隔(欧洲 Excel 的语言习惯)文件时很有用:

sql
\pset format unaligned
\pset fieldsep '\t'
SELECT id, name FROM demo;
text
1	alpha
2

配套的 fieldsep_zero 把分隔符换成 NUL 字节,配合 xargs -0 等工具处理「内容里什么怪字符都可能出现」的数据。recordsep 与 recordsep_zero 则控制行与行之间的分隔(默认换行符),极少改动但了解即可。

快捷命令 \f 等价于设置 fieldsep:\f ','。

pager 与 numericlocale ​

结果超过一屏时 psql 会调用外部分页器(less 等)翻页,这在交互时方便,在脚本里却是灾难——输出可能被卡在分页器里没人按空格。pager 三个取值:

取值行为
off永不使用分页器
on(默认)输出超出终端高度且终端可用时使用
always无论是否超屏都使用

脚本环境的经典写法是环境变量与 \pset 双保险:

bash
export PSQL_PAGER='less -S'   # 横向不折行,宽表利器;也可用 PAGER
psql -P pager=off -c 'SELECT * FROM big_table' > result.txt

PSQL_PAGER 优先于 PAGER,两者都可以带参数(如 less -S)。numericlocale 则控制对齐格式里是否按本地化习惯给数字加千分位分隔符(如 1.234,5),做财务报表时有感,平时保持默认 off。

输出重定向:\g file 与 \o ​

两条重定向路径的语义差异是本页最容易混淆的点:

命令生效范围典型用途
\g 文件只对当前查询缓冲区这一次执行生效偶尔把某条结果存档
\g | 命令当前查询结果通过管道送给外部命令\g | gzip > /tmp/r.gz
\o 文件持续重定向所有输出,直到裸 \o 关闭批量生成一份完整报告
\o | 命令后续输出持续进入管道\o | mailx -s report dba@example.com

\o 期间,连 \d 元命令的输出、错误信息都会进入目标文件,这对「生成完整巡检报告」是优点,对「只想导数据」则是陷阱——记得把 footer、\t 等装饰先处理好。

sql
\o /tmp/report.html
\pset format html
\pset title '慢查询 TOP 20'
SELECT pid, now() - query_start AS dur, left(query, 80) AS query
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY dur DESC
LIMIT 20;
\o
\pset format aligned

表格标题、HTML 属性与剩余选项 ​

前文覆盖了日常 90% 的场景,剩下几个选项在特定场合各显其能:

sql
-- title:给表格一个标题(aligned 下显示在表格上方,HTML 下渲染为 <caption>)
\pset title '活跃会话巡检'
SELECT pid, usename, state FROM pg_stat_activity LIMIT 3;
text
活跃会话巡检
 pid  | usename | state
------+---------+--------
 1201 | app_rw  | active
 1202 | etl     | idle
(2 rows)
  • tableattr(快捷命令 \T):HTML 格式下给 <table> 标签追加属性,如 \pset tableattr 'class="data-table" id="sess"',产出物可直接嵌入有样式的页面;
  • columns:wrapped 格式的目标宽度与分页判断依据,宽终端看宽表时显式设置 \pset columns 160 比 auto 检测更稳;
  • fieldsep_zero/recordsep_zero:以 NUL 作分隔,配合 xargs -0 消费「内容里什么都有」的数据;
  • unicode_border_linestyle/unicode_column_linestyle/unicode_header_linestyle:linestyle=unicode 时三类框线的细分子风格(single/double),装饰控的最爱;
  • border 在 unaligned 下的行为:非零 border 会让 unaligned 输出在行间加分隔行为,具体表现依版本而异,脚本里保持默认 0 即可。

这些选项共同特点是「低频但救命」——写报告、做演示、对接挑剔的下游时,知道自己手里有这些旋钮,比记住每个默认值重要得多。

\gdesc:不执行也能看列结构 ​

\g 家族还有一个常被忽略的成员:\gdesc 显示当前查询缓冲区的列名与类型,但不执行查询:

sql
SELECT pid,
       usename,
       now() - query_start AS duration,
       pg_size_pretty(pg_total_relation_size('orders')) AS table_size
\gdesc
text
  Column   |           Type
-----------+---------------------------
 pid       | integer
 usename   | name
 duration  | interval
 table_size| text

写长查询时先 \gdesc 验证别名与类型,再决定是否真正执行——对开销大的查询(重聚合、跨库 JOIN 的 FDW)非常实用,也让上一页变量篇「列名即变量名」的 \gset 前置检查有了工具。

\pset format csv 与 \copy 的组合拳 ​

把查询结果落成 CSV 文件,有两条可用的路径,适用场景不同:

路径 A:格式化导出(\pset format csv + \o)

sql
\pset format csv
\pset footer off
\o /tmp/orders.csv
SELECT id, status, amount, created_at FROM orders WHERE created_at >= '2026-09-01';
\o
\pset format aligned
  • 优点:所见即所得,SELECT 里怎么写、文件里就是什么,支持任意复杂查询(含 JOIN、聚合、表达式列名);
  • 缺点:数据先完整地经过 psql 的格式化层,几十万行以上明显偏慢。

路径 B:协议级导出(\copy)

sql
\copy (SELECT id, status, amount, created_at FROM orders WHERE created_at >= '2026-09-01') TO '/tmp/orders2.csv' WITH (FORMAT csv, HEADER true)
  • 优点:流式传输,快一个数量级;
  • 缺点:写法上是一条 \copy 命令,长 SQL 塞在括号里不够优雅;列名直接取自 SELECT 输出。

经验法则:几百行以内的「报表级」导出用路径 A(尤其需要 HTML/标题等装饰时);上万行的「数据级」导出必须用路径 B。两者也可以混用:先用 \o+format csv 调试查询、确认结果正确,再把同一段 SELECT 换进 \copy 里放量导出。

\watch:定时观察同一查询 ​

\watch [秒数] 会反复执行当前查询缓冲区里的 SQL,默认每 2 秒一次,Ctrl+C 停止。它是 psql 内置的「简易监控循环」,配合 \pset expanded auto 观察宽视图尤其舒服:

sql
SELECT count(*) AS active,
       count(*) FILTER (WHERE wait_event_type IS NOT NULL) AS waiting
FROM pg_stat_activity
WHERE state <> 'idle'
\watch 5
text
 active | waiting
--------+---------
      7 |       1
(1 row)
等待 5 秒后自动重复……

PostgreSQL 18 放宽了 \watch 的最小间隔限制(最短可到毫秒级),并支持 min_interval 等选项,做亚秒级观测前请查阅所用版本的文档。要注意 \watch 期间客户端会一直「发查询-收结果」空转,对服务器有轻微压力,不适合在生产主库上高频运行;长时间监控请交给专业的监控系统。

.psqlrc 持久化与 PSQLRC、PSQL_PAGER ​

每次都手敲 \pset 终究麻烦。psql 启动时会自动读取用户的启动文件,把个性化设置持久化:

  • Linux/macOS:~/.psqlrc(环境变量 PSQLRC 可改路径);
  • Windows:%APPDATA%\postgresql\psqlrc.conf。

文件内容就是一串普通的 psql 元命令:

text
-- ~/.psqlrc
\pset null '[NULL]'
\pset expanded auto
\pset linestyle unicode
\pset footer off
\set ON_ERROR_STOP on
\set PROMPT1 '%n@%M:%>/ %R%# '
\timing on

几个必须知道的细节:

  1. -X(或 --no-psqlrc)跳过启动文件。写脚本时务必加上:psql -X ...,避免用户个人配置污染脚本行为——尤其是 \pset format、\pset null 这类会改变输出契约的设置。
  2. PGOPTIONS 与启动文件的分工:.psqlrc 管客户端展示,服务器端的会话参数(如 statement_timeout)也可以在 .psqlrc 里用 SET 语句设置,但脚本里同样建议用 -c 'SET ...' 显式声明。
  3. PSQL_PAGER 决定 \pset pager 调用哪个分页器,常见配置 export PSQL_PAGER='less -S'(-S 表示长行不折行,配合宽表、横向滚动查看)。
  4. .psqlrc 里写 -- 注释是合法的,psql 会原样执行文件中的每一行元命令与 SQL。

实战示例 ​

示例一:一条命令导出 Excel 友好的 CSV ​

bash
psql -X -d appdb -v ON_ERROR_STOP=1 <<'SQL'
\pset format csv
\pset footer off
\pset null ''
\o /tmp/daily_summary.csv
SELECT date_trunc('day', created_at)::date AS day,
       status,
       count(*) AS cnt,
       round(sum(amount), 2) AS amount
FROM orders
WHERE created_at >= current_date - interval '7 days'
GROUP BY 1, 2
ORDER BY 1, 2;
\o
SQL

要点:-X 屏蔽个人启动文件保证输出契约稳定;\pset null '' 让 NULL 落成空单元格(Excel 里显示为空白而非 [NULL] 字样)。

示例二:生成可发送的 HTML 巡检报告 ​

bash
psql -X -d appdb <<'SQL' > /tmp/inspect.html
\pset format html
\pset border 2
\pset title '数据库巡检报告 - 生成时间见下行'
SELECT now() AS generated_at;
\pset title '活跃会话'
SELECT pid, usename, application_name, state, wait_event_type
FROM pg_stat_activity WHERE state <> 'idle';
\pset title '最大的 10 张表'
SELECT relname,
       pg_size_pretty(pg_total_relation_size(relid)) AS total_size
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 10;
SQL

一条 psql 会话产出一份含多个表格的完整 HTML,浏览器直接打开即可转发。

示例三:\watch 观察锁等待 ​

sql
\pset expanded auto
SELECT blocked.pid     AS blocked_pid,
       blocked.wait_event_type,
       blocking.pid    AS blocking_pid,
       left(blocking.query, 60) AS blocking_query
FROM pg_stat_activity blocked
JOIN pg_stat_activity blocking
  ON blocking.pid = pg_blocking_pids(blocked.pid)[1]
WHERE blocked.wait_event_type = 'Lock'
\watch 3

Ctrl+C 退出观察。若想保留观察轨迹,先 \o /tmp/lock_watch.log 再 \watch。

示例四:一份团队通用的 .psqlrc ​

text
-- ~/.psqlrc —— 交互体验向配置,脚本请始终使用 psql -X
\pset null '[NULL]'
\pset expanded auto
\pset linestyle unicode
\pset footer off
\pset pager on

\timing on
\set ON_ERROR_STOP on
\set QUIET on

-- 默认提示符:用户@主机:端口 库名
\set PROMPT1 '%n@%M:%> %~ %# '
\set PROMPT2 '  %R '

-- 常用变量
\set act 'SELECT pid, state, wait_event_type, left(query,60) FROM pg_stat_activity WHERE state <> ''idle'';'
\set locks 'SELECT * FROM pg_locks WHERE NOT granted;'
\set size 'SELECT pg_size_pretty(pg_database_size(current_database())) AS db_size;'

配置后,交互会话里直接敲 :act 就能查活跃会话(SQL 里插值用法见下一页《psql 变量与 \gset》)。

注意事项 ​

\pset 只影响展示,不影响数据。 它不会改变查询计划、不会改变返回值本身,但会改变「人从终端上看到什么」。排查问题时如果发现「终端里明明有值、程序里却是 NULL」,先检查 \pset null 是否被启动文件改过。

脚本必须用 -X 隔离 .psqlrc。 用户启动文件里的 \pset format csv、\pset null、\t 都会改变脚本输出格式。所有自动化脚本一律 psql -X,让行为只由命令行参数决定,这是可重复性的底线。

\o 会吞掉错误与元命令输出。 \o 文件 期间错误信息也进文件,脚本里可能「明明失败了却没人发现」。结合 -v ON_ERROR_STOP=1 使用,失败立即退出。

unaligned 的 fieldsep 不做转义。 如果字段值本身含 |,输出会错位。给程序消费的数据请用 format csv(有标准引号转义)或 \copy,不要用裸的 fieldsep。

pager 会让脚本挂住。 在自动化环境(CI、cron)里若终端检测异常,输出可能进入等待输入的分页器。脚本内显式 \pset pager off,或环境里 export PSQL_PAGER=cat 兜底。

watch 不是监控替代品。 \watch 单连接串行轮询,间隔过小会对服务器形成持续压力,也无法告警、无历史曲线。生产监控交给 Prometheus + postgres_exporter 这类方案(详见监控章节),\watch 用于人工临时观察。

宽表优先 expanded auto 而不是调 border。 遇到看不清的宽表,先 \x auto,多数情况立刻可读;盲目加大终端宽度或调边框解决不了问题。

Windows 下的启动文件名不同。 是 %APPDATA%\postgresql\psqlrc.conf 而非 .psqlrc,网上照抄 Linux 路径无效;另外 Windows 控制台的默认代码页可能导致 unicode 线型乱码,此时回退 \pset linestyle ascii。

\pset 的选项名与取值要原样核对。 手滑写成 \pset expand on(少了 ed)会静默创建一个无意义的用户变量而不是报错;关键的输出脚本建议在开头 \echo 当前的 \pset 状态快照,留档可查。

title/tableattr 只影响「有表格语义」的格式。 在 unaligned/csv 下设置标题不会有任何效果;想要「CSV 也带一行说明」只能自己在 \o 里 echo,别指望格式层代劳。

最佳实践 ​

  1. 在 ~/.psqlrc 里固化三件套:\pset null '[NULL]'、\pset expanded auto、\pset linestyle unicode。 这三项显著提升日常可读性,且不影响任何脚本(脚本都带 -X)。
  2. 交互用 expanded auto,导出用 csv/copy。 形成肌肉记忆后,「看数据」与「搬数据」两条路径互不干扰。
  3. 给 NULL 定一个显眼的显示记号。 空白与 NULL 的混淆是数据分析里最隐蔽的坑之一,一个 [NULL] 记号能避免大量误判。
  4. 导出 CSV 之前先关 footer、清 null 记号。 \pset footer off + \pset null '',保证文件里只有干净的数据行。
  5. 脚本一律 psql -X 并显式声明所需格式。 让输出格式成为脚本的一部分,而不是用户环境的巧合。
  6. 用 \o | 管道衔接 Unix 工具链。 \o | gzip > /tmp/r.gz、\o | column -t -s'|' 这类组合让 psql 无缝融入 shell 流水线。
  7. \g file 用作「随手存档」,\o 用作「成篇报告」。 一次性结果用前者,多查询汇总用后者,用完记得裸 \o 关闭。
  8. 给分页器配 less -S。 宽表横向滚动远比折行易读,export PSQL_PAGER='less -S' 一行环境变量长期受益。
  9. \watch 观察要设间隔、要会退出。 3~10 秒的间隔足够大多数排障场景;观察锁等待时注意 \watch 本身也可能被阻塞视图里的查询影响。
  10. 把常用巡检 SQL 存成 .psqlrc 变量。 如示例四的 :act、:locks,把重复敲的长查询变成一个短词,这是 psql 效率提升最明显的习惯。
  11. 文档排版场景直接用 asciidoc/latex 格式。 与其手工把查询结果粘成表格,不如 \pset format asciidoc + \o 一键产出,改数后重跑即可。
  12. 升级 psql 版本后重验脚本输出。 大版本间格式化细节(如 unicode 线型、CSV 转义)偶有微调,核心导出脚本在升级演练时纳入回归清单。

下一节

继续学习:psql 变量与 \gset

参考链接 ​