↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

百科 / 命令行工具 / 服务端程序

pg_test_timing

pg_test_timing — 测量计时开销

当前查看 PostgreSQL 18.6。

说明

pg_test_timing — 测量计时开销

手册中的可执行程序
pg_test_timing
程序版本
18.6
参考清单
服务端程序
选项定义组
3

用法

pg_test_timing [ option ...]

手册中的选项

选项与参数说明
-d duration --duration= duration指定测试持续时间,以秒为单位。持续时间越长,精度会略有提高,也更可能发现系统时钟倒退的问题。默认测试持续时间为 3 秒。
-V --version打印 pg_test_timing 版本并退出。
-? --help显示有关 pg_test_timing 命令行参数的帮助信息并退出。

手册定义

pg_test_timing

pg_test_timing — 测量计时开销

大纲

pg_test_timing [option...]

说明

pg_test_timing是一个用于测量系统计时开销的工具,并确认系统时间不会倒退。收集计时数据较慢的系统,可能会给出不够精确的 EXPLAIN ANALYZE结果。

选项

pg_test_timing接受下列命令行选项:

-d duration
--duration=duration

指定测试持续时间,以秒为单位。持续时间越长,精度会略有提高,也更可能发现系统时钟倒退的问题。默认测试持续时间为 3 秒。

-V
--version

打印pg_test_timing版本并退出。

-?
--help

显示有关pg_test_timing命令行参数的帮助信息并退出。

用法

结果解读

良好的结果应表明,大多数(>90%)单次计时调用的耗时少于一微秒。每轮循环的平均开销会更低,低于 100 纳秒。下面的示例来自使用 TSC 时钟源的 Intel i7-860 系统,表现非常出色:

Testing timing overhead for 3 seconds.
Per loop time including overhead: 35.96 ns
Histogram of timing durations:
  < us   % of total      count
     1     96.40465   80435604
     2      3.59518    2999652
     4      0.00015        126
     8      0.00002         13
    16      0.00000          2

注意,每轮循环耗时与直方图使用的单位不同。循环耗时的分辨率可以达到几纳秒(ns),而单次计时调用的分辨率只能达到一微秒(us)。

测量执行器计时开销

当查询执行器使用EXPLAIN ANALYZE运行语句时,除了显示汇总信息之外,还会对各个操作分别计时。可以使用psql程序统计行数,以检查你的系统上的这类开销:

CREATE TABLE t AS SELECT * FROM generate_series(1,100000);
\timing
SELECT COUNT(*) FROM t;
EXPLAIN ANALYZE SELECT COUNT(*) FROM t;

在所测的 i7-860 系统上,普通计数查询耗时 9.8 ms,而 EXPLAIN ANALYZE版本耗时 16.6 ms,两者都处理了略多于 100,000 行。这 6.8 ms 的差异意味着每行的计时开销为 68 ns,大约是 pg_test_timing 估计值的两倍。即便是这样相对较小的开销,也会让完整计时的计数语句耗时增加近 70%。对于更复杂的查询,计时开销带来的问题就不会这么明显。

更改时钟源

在某些较新的 Linux 系统上,可以随时更改用于收集计时数据的时钟源。第二个示例展示了在产生上述快速结果的同一台系统上,切换到较慢的 acpi_pm 时钟源可能导致的性能下降:

# cat /sys/devices/system/clocksource/clocksource0/available_clocksource
tsc hpet acpi_pm
# echo acpi_pm > /sys/devices/system/clocksource/clocksource0/current_clocksource
# pg_test_timing
Per loop time including overhead: 722.92 ns
Histogram of timing durations:
  < us   % of total      count
     1     27.84870    1155682
     2     72.05956    2990371
     4      0.07810       3241
     8      0.01357        563
    16      0.00007          3

在这种配置下,上面的示例EXPLAIN ANALYZE需要 115.9 ms。这意味着计时开销达到 1061 ns,同样只是本工具直接测得数值的一个小倍数。如此之大的计时开销说明,实际查询本身只占已统计时间的一小部分,其余大多耗费在开销上。在这种配置下,任何包含大量计时操作的EXPLAIN ANALYZE总计值,都会因计时开销而被显著抬高。

FreeBSD 也允许动态更改时钟源,并会记录启动期间所选计时器的信息:

# dmesg | grep "Timecounter"
Timecounter "ACPI-fast" frequency 3579545 Hz quality 900
Timecounter "i8254" frequency 1193182 Hz quality 0
Timecounters tick every 10.000 msec
Timecounter "TSC" frequency 2531787134 Hz quality 800
# sysctl kern.timecounter.hardware=TSC
kern.timecounter.hardware: ACPI-fast -> TSC

其他系统可能只允许在启动时设置时钟源。在较旧的 Linux 系统上,内核设置“clock”是进行此类更改的唯一方式。即使在某些较新的系统上,你能看到的时钟源选项也可能只有“jiffies”。jiffies 是较早的 Linux 软件时钟实现,如果底层计时硬件足够快,它也能提供良好的解析度,如下例所示:

$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
jiffies
$ dmesg | grep time.c
time.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.
time.c: Detected 2400.153 MHz processor.
$ pg_test_timing
Testing timing overhead for 3 seconds.
Per timing duration including loop overhead: 97.75 ns
Histogram of timing durations:
  < us   % of total      count
     1     90.23734   27694571
     2      9.75277    2993204
     4      0.00981       3010
     8      0.00007         22
    16      0.00000          1
    32      0.00000          1

时钟硬件和计时准确性

在计算机上收集精确的计时信息,通常依赖精度各异的硬件时钟。对于某些硬件,操作系统几乎可以将系统时钟时间直接传递给程序。系统时钟也可能来自一种只提供计时中断、按已知时间间隔周期性地产生滴答信号的芯片。无论哪种情况,操作系统内核都会提供一个屏蔽这些细节的时钟源。不过,这种时钟源的精度以及返回结果的速度,都取决于底层硬件。

不准确的计时可能导致系统不稳定。对时钟源的任何更改都应十分谨慎地测试。操作系统的默认设置有时会偏向可靠性,而不是追求最佳精度。如果你使用的是虚拟机,还应了解与其兼容的推荐时钟源。虚拟硬件在模拟计时器时会面临额外困难,厂商通常还会针对不同操作系统给出特定的设置建议。

时间戳计数器(TSC)时钟源是当前一代 CPU 上可用的最精确时钟源。当操作系统支持它且 TSC 时钟本身可靠时,它是跟踪系统时间的首选方式。TSC 也可能因多种原因无法提供精确的计时源,从而变得不可靠。较旧的系统中,TSC 时钟可能会随 CPU 温度变化,因此不适合用于计时。在某些较旧的多核 CPU 上使用 TSC,还可能导致不同核心报告的时间彼此不一致。这会引起时间倒退,而本程序正是用来检查这类问题的。即便在最新的系统上,若节能配置过于激进,也可能无法提供精确的 TSC 计时。

较新的操作系统可能会检测已知的 TSC 问题,并在发现时切换到更慢但更稳定的时钟源。如果你的系统支持 TSC 计时却没有默认使用它,那么禁用它很可能是有充分理由的。某些操作系统也可能无法正确检测所有潜在问题,或者即使已知 TSC 不准确,仍允许继续使用它。

如果系统上有高精度事件计时器(HPET),并且 TSC 不准确,那么 HPET 就是系统更倾向使用的计时器。计时器芯片本身可编程,最高可提供 100 纳秒的解析度,但在你的系统时钟中未必能看到这么高的准确性。

高级配置与电源接口(ACPI)提供了一种电源管理(PM)计时器,Linux 将其称为 acpi_pm。由 acpi_pm 派生的时钟在最佳情况下可提供 300 纳秒的解析度。

较旧 PC 硬件使用的计时器包括 8254 可编程间隔计时器(PIT)、实时时钟(RTC)、高级可编程中断控制器(APIC)计时器以及 Cyclone 计时器。这些计时器的目标解析度是毫秒级。

另见

EXPLAIN

文档与源码

来源构建
版本
18.6
构建
https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2
来源指纹
ee8d1a3612338fd9adf250730cb640fcc5233b5491337cc00a316a44e3a0b9f8

版本比较

PostgreSQL 17 → 18: 无变化。

比较已记录的接口与属性,排除来源指纹和构建元数据。某个样本中没有记录,不能据此判断实际引入或移除的版本。

相关条目

导出 JSON · 返回命令行工具 · 收录范围为 PostgreSQL 10 至 20;最早采样版本不一定是实际引入版本。