字段太多看不全,ksql 的展开模式和输出控制怎么用?

585
Category: 
开发交流

MySQL 里查宽表,字段多了输出就会折行,列对应关系容易看乱。MySQL 的解法是在 SQL 末尾加 \G,把每行的字段竖着列出来。ksql 里处理这个问题的方式不同——通过几个元命令控制整个会话的输出行为,不用每条 SQL 末尾单独加。

这篇在 KingbaseES V009R001C010 环境里验证:\x(展开模式)、\x auto(自动判断)、\timing(执行耗时)、\pset border(边框调整)、\o(输出重定向)。演示在 app_db 库的 app_schema.t_meta_demo 表上进行,用 app_user 连接,进入后先执行 set search_path to app_schema, public 让后续查询不带 schema 前缀。

默认输出下的宽表问题

关掉分页器,直接查全表:

\pset pager off
select * from t_meta_demo;

执行效果:

app_db=> \pset pager off
Pager usage is off.
app_db=> select * from t_meta_demo;
 id | order_no  | user_name | status  |  amount | created_at
----+-----------+-----------+---------+---------+-------------------------------
  1 | ORD-20240601-001 | alice | paid | 1280.50 | 2026-06-12 14:39:09.209084
  2 | ORD-20240601-002 | bob   | pending | 360.00 | 2026-06-12 14:39:09.209084
  3 | ORD-20240601-003 | carol | shipped | 899.00 | 2026-06-12 14:39:09.209084
  4 | ORD-20240601-004 | alice | paid | 75.20 | 2026-06-12 14:39:09.209084
  5 | ORD-20240601-005 | dave  | refund | 2100.00 | 2026-06-12 14:39:09.209084
(5 rows)
app_db=>

t_meta_demoidorder_nouser_namestatusamountcreated_at 六个字段,终端宽度不够时每行折成多行,字段名和值的对应关系很难一眼看清。这就是 \x 要解决的问题。

\x 开关:竖排展开和关闭

打开展开模式,再查一次:

\x
select * from t_meta_demo limit 2;

再执行一次 \x 关掉,对比两次输出:

\x
select * from t_meta_demo limit 2;

执行效果:

app_db=>\x
Expanded display is on.
app_db=> select * from t_meta_demo limit 2;
-[ RECORD 1 ]-------------------------
id         | 1
order_no   | ORD-20240601-001
user_name  | alice
status     | paid
amount     | 1280.50
created_at | 2026-06-12 14:39:09.209084
-[ RECORD 2 ]-------------------------
id         | 2
order_no   | ORD-20240601-002
user_name  | bob
status     | pending
amount     | 360.00
created_at | 2026-06-12 14:39:09.209084

app_db=>\x
Expanded display is off.
app_db=> select * from t_meta_demo limit 2;
 id | order_no         | user_name | status  | amount | created_at
----+------------------+-----------+---------+--------+-------------------------------
  1 | ORD-20240601-001 | alice     | paid    | 1280.50| 2026-06-12 14:39:09.209084
  2 | ORD-20240601-002 | bob       | pending | 360.00 | 2026-06-12 14:39:09.209084
(2 rows)

\x 打开后 ksql 提示 Expanded display is on,输出格式从横排表格变成竖列展示,每个字段单独一行,格式是 字段名 | 值。再次执行 \x 提示 Expanded display is off,恢复横排。

MySQL 里竖排显示用的是 select ... \G,写在 SQL 末尾,只对那一条语句生效。\x 是会话级开关,打开以后所有查询都走竖排格式,不需要每条 SQL 后面加。连续查几张宽表时,\x\G 省事得多。

\x auto:让 ksql 自己决定要不要展开

手动切 \x 来回有点麻烦。\x auto 模式下 ksql 自动判断:

\x auto

ksql 返回 Expanded display is used automatically

查单行结果:

select * from t_meta_demo where order_no = 'ORD-20240601-001';

再查多行:

select * from t_meta_demo;

执行效果:

app_db=> \x auto
Expanded display is used automatically.
app_db=> select * from t_meta_demo where order_no = 'ORD-20240601-001';
-[ RECORD 1 ]-------------------------
id         | 1
order_no   | ORD-20240601-001
user_name  | alice
status     | paid
amount     | 1280.50
created_at | 2026-06-12 14:39:09.209084

app_db=> select * from t_meta_demo;
 id | order_no         | user_name | status  |  amount | created_at
----+------------------+-----------+---------+---------+-------------------------------
  1 | ORD-20240601-001 | alice     | paid    | 1280.50 | 2026-06-12 14:39:09.209084
  2 | ORD-20240601-002 | bob       | pending | 360.00  | 2026-06-12 14:39:09.209084
  3 | ORD-20240601-003 | carol     | shipped | 899.00  | 2026-06-12 14:39:09.209084
  4 | ORD-20240601-004 | alice     | paid    | 75.20   | 2026-06-12 14:39:09.209084
  5 | ORD-20240601-005 | dave      | refund  | 2100.00 | 2026-06-12 14:39:09.209084
(5 rows)

单行查询下 ksql 自动用了竖排展开;多行查询 ksql 判断终端宽度够用,直接输出横排表格。

\x auto 的判断依据是当前终端宽度,不是字段数量。同一张表,终端窗口调窄 ksql 更倾向于展开,调宽相同查询可能回到横排。MySQL 里没有这个模式,\G 每次都要手写在 SQL 末尾。

\timing 显示执行耗时

关掉展开模式,开启计时:

\x off
\timing

执行几条查询观察耗时:

select count(*) from t_meta_demo;
select * from t_meta_demo where status = 'paid';
select user_name, sum(amount) from t_meta_demo group by user_name;

执行效果:

app_db=> \x off
Expanded display is off.
app_db=> \timing
Timing is on.

app_db=> select count(*) from t_meta_demo;
 count
-------
     5
(1 row)
Time: 1.266 ms

app_db=> select * from t_meta_demo where status = 'paid';
 id | order_no         | user_name | status | amount | created_at
----+------------------+-----------+--------+--------+-------------------------------
  1 | ORD-20240601-001 | alice     | paid   | 1280.50| 2026-06-12 14:39:09.209084
  4 | ORD-20240601-004 | alice     | paid   | 75.20  | 2026-06-12 14:39:09.209084
(2 rows)
Time: 0.542 ms

app_db=> select user_name, sum(amount) from t_meta_demo group by user_name;
 user_name |  sum
-----------+---------
 dave      | 2100.00
 bob       |  360.00
 carol     |  899.00
 alice     | 1355.70
(4 rows)
Time: 2.625 ms

\timing 开启后提示 Timing is on,每条 SQL 执行完都会跟着一行 Time: x.xxx ms

MySQL 里看执行耗时通常需要 show profiles 或者借助客户端工具,ksql 里 \timing 打开以后自动附在每个结果后面,不用额外操作。

\timing 给的是客户端侧的壁钟时间,包含网络往返和客户端处理,只适合粗粒度判断某条查询快不快。精确分析 SQL 是否走了索引、各执行节点耗时分布,要用 EXPLAIN (ANALYZE, BUFFERS),不能把 \timing 当性能分析工具来用。

\pset border 调整输出边框

关掉计时,演示三种边框样式:

\timing off

默认边框(border 1):

\pset border 1
select order_no, user_name, status, amount from t_meta_demo limit 3;

无边框(border 0):

\pset border 0
select order_no, user_name, status, amount from t_meta_demo limit 3;

双线边框(border 2):

\pset border 2
select order_no, user_name, status, amount from t_meta_demo limit 3;

执行效果:

app_db=> \timing off
Timing is off.

app_db=> \pset border 1
Border style is 1.
app_db=> select order_no, user_name, status, amount from t_meta_demo Limit 3;
     order_no     | user_name | status  | amount
------------------+-----------+---------+--------
 ORD-20240601-001 | alice     | paid    | 1280.50
 ORD-20240601-002 | bob       | pending | 360.00
 ORD-20240601-003 | carol     | shipped | 899.00
(3 rows)

app_db=> \pset border 0
Border style is 0.
app_db=> select order_no, user_name, status, amount from t_meta_demo Limit 3;
order_no         user_name status  amount
ORD-20240601-001 alice     paid    1280.50
ORD-20240601-002 bob       pending 360.00
ORD-20240601-003 carol     shipped 899.00
(3 rows)

app_db=> \pset border 2
Border style is 2.
app_db=> select order_no, user_name, status, amount from t_meta_demo Limit 3;
+------------------+-----------+---------+--------+
|     order_no     | user_name | status  | amount |
+------------------+-----------+---------+--------+
| ORD-20240601-001 | alice     | paid    | 1280.50|
| ORD-20240601-002 | bob       | pending | 360.00 |
| ORD-20240601-003 | carol     | shipped | 899.00 |
+------------------+-----------+---------+--------+
(3 rows)

三种样式的差别:

  • border 1:列之间用 | 分隔,标题行下有 +---+---+ 形式的分隔线,是默认样式
  • border 0:去掉所有分隔符,列之间只有空格,标题和数据之间用短横线对齐
  • border 2:整个结果集外面加一圈完整边框,顶部、底部、标题和数据之间都有分隔线

\pset border 只改显示格式,不影响数据,切换后立即生效。MySQL 客户端输出的边框样式固定,ksql 这里可以按需调整。border 0 在把终端输出粘贴进文档时最有用,不用手动清格线。演示完以后恢复默认:

\pset border 1

\o 把输出写进文件

在交互会话里把查询结果重定向到文件,不需要退出去用 shell 重定向:

\pset border 1
\o /tmp/ksql-output.txt
select order_no, user_name, status, amount from t_meta_demo;
\o

执行效果:

app_db=> \pset border 1
Border style is 1.
app_db=> \o /tmp/ksql-output.txt
app_db=> select order_no, user_name, status, amount from t_meta_demo;
app_db=> \o

另一个终端查看文件:

[root@todoitbo ~]# cat /tmp/ksql-output.txt
     order_no     | user_name | status  |  amount
------------------+-----------+---------+---------
 ORD-20240601-001 | alice     | paid    | 1280.50
 ORD-20240601-002 | bob       | pending | 360.00
 ORD-20240601-003 | carol     | shipped | 899.00
 ORD-20240601-004 | alice     | paid    | 75.20
 ORD-20240601-005 | dave      | refund  | 2100.00
(5 rows)

\o /tmp/ksql-output.txt 打开后,ksql 不再把查询结果输出到终端——select 执行后提示符直接回来,没有任何表格输出,结果都写进了文件。\o 不带参数,关闭重定向,恢复终端输出。

有一个坑容易踩:关闭重定向必须用 \o 不带任何参数。忘了关的话,后续所有查询输出包括元命令的提示都会继续写文件,终端里什么都看不到,很容易以为命令没执行。MySQL 里在交互会话内导出结果通常要借助外部工具,ksql 里 \o 可以直接在会话内切换,用完记得关。

Comments 1
/ 1000
Trending
New
很实用
Like
Comment
2
1
Favorite