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接受下列命令行选项:
-dduration--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 18 → 19: 属性变化。
以下差异保留原始字段名与英文源描述。
--- PostgreSQL 18
+++ PostgreSQL 19
@@ -1,6 +1,14 @@
{
"environment": [],
"options": [
+ {
+ "description": "Specifies the cutoff percentage for the list of exact observed timing durations (that is, the changes in the system clock value from one reading to the next). The list will end once the running percentage total reaches or exceeds this value, except that the largest observed duration will always be printed. The default cutoff is 99.99.",
+ "names": [
+ "-c cutoff",
+ "--cutoff= cutoff"
+ ],
+ "signature": "-c cutoff --cutoff= cutoff"
+ },
{
"description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.",
"names": [
比较已记录的接口与属性,排除来源指纹和构建元数据。某个样本中没有记录,不能据此判断实际引入或移除的版本。
相关条目
导出 JSON · 返回命令行工具 · 收录范围为 PostgreSQL 10 至 20;最早采样版本不一定是实际引入版本。