数据库中的 CPU 利用率究竟意味着什么?
What does CPU utilisation in databases actually mean?
我有两种查询运行,
1.A 故意引入查询以在大约 10 columns.This 使用 CPU 中执行排序(排序),因为排序是 CPU 密集型操作。
涉及的场景 运行 查询耗时 30 秒,运行 大约 100 个同时使用 100 个不同的连接 tables.CPU 在 32 核机器上的使用率约为 85%在所有 32 个内核和所有 100 个并行查询上 运行。
2.Inserting table 上的一百万行。
我不明白为什么这会消耗 CPU,因为这纯粹是磁盘 I/O。但是我在单个 table 上使用 100 个同步 connections/threads 并且那些 table 上没有索引,现在插入不是加载数据的最快方法,但这里的要点是它在大约 10 [=] 上消耗了 CPU 大约 32% 的时间33=] 比上面的小很多,但我仍然只是好奇。
我可能是错的,因为 Wal 归档和查询日志都打开了 - 这是否有助于 CPU.I 我假设没有,因为它们也是磁盘 IO。
除了 postgres,这台机器上没有其他 process/application running/installed。
如果您的 table 有一个主键,那么它就有一个隐式索引。
如果 table 有一个主键,那么它可能会被存储为一个 b 树而不是一个简单的平面 table;我不清楚这一点,因为我的 postgres-fu 这些年来已经减弱,但是许多 DBMS 使用主键作为 b 树的默认聚类键,并且只将所有内容存储在 b 树中。管理那个 b-tree 需要大量的 CPU.
此外,如果您从 100 个线程和连接中插入,则 postgres 必须执行锁定以保持内部数据结构的一致性。争夺锁会消耗大量 CPU,并且在具有许多 CPU 的机器上尤其难以有效地完成 - 获取单个互斥量需要系统 ala 中每个 CPU 的合作缓存一致性协议。
您可能想尝试使用不同数量的线程,同时测量总体运行时间和 cpu 使用情况 - 您可能会发现,例如 8 个线程,使用的总 CPU 是 1/当前使用量的十分之一,但仍能在原始时间的 110-150% 内完成工作。这肯定是锁定争用正在扼杀您的 CPU 使用。
很多不同的东西:
- CPU查询计划的时间和执行器中查询执行的逻辑
- 将元组的文本表示形式转换为其磁盘格式。解析日期等。
- 日志输出
- 正在处理事务日志
- 插入要写入的页面时正在写入 shared_buffers,扫描 shard_buffers 以查找要写入的页面
- 用于锁管理的进程间通信
- 在检查唯一性、在索引中插入新键等时扫描内存中缓存的索引副本
- .....
如果您真的想知道有趣的细节,请启动 perf
并启用堆栈跟踪以查看 CPU 时间花在哪里。
我有两种查询运行,
1.A 故意引入查询以在大约 10 columns.This 使用 CPU 中执行排序(排序),因为排序是 CPU 密集型操作。
涉及的场景 运行 查询耗时 30 秒,运行 大约 100 个同时使用 100 个不同的连接 tables.CPU 在 32 核机器上的使用率约为 85%在所有 32 个内核和所有 100 个并行查询上 运行。
2.Inserting table 上的一百万行。
我不明白为什么这会消耗 CPU,因为这纯粹是磁盘 I/O。但是我在单个 table 上使用 100 个同步 connections/threads 并且那些 table 上没有索引,现在插入不是加载数据的最快方法,但这里的要点是它在大约 10 [=] 上消耗了 CPU 大约 32% 的时间33=] 比上面的小很多,但我仍然只是好奇。
我可能是错的,因为 Wal 归档和查询日志都打开了 - 这是否有助于 CPU.I 我假设没有,因为它们也是磁盘 IO。
除了 postgres,这台机器上没有其他 process/application running/installed。
如果您的 table 有一个主键,那么它就有一个隐式索引。
如果 table 有一个主键,那么它可能会被存储为一个 b 树而不是一个简单的平面 table;我不清楚这一点,因为我的 postgres-fu 这些年来已经减弱,但是许多 DBMS 使用主键作为 b 树的默认聚类键,并且只将所有内容存储在 b 树中。管理那个 b-tree 需要大量的 CPU.
此外,如果您从 100 个线程和连接中插入,则 postgres 必须执行锁定以保持内部数据结构的一致性。争夺锁会消耗大量 CPU,并且在具有许多 CPU 的机器上尤其难以有效地完成 - 获取单个互斥量需要系统 ala 中每个 CPU 的合作缓存一致性协议。
您可能想尝试使用不同数量的线程,同时测量总体运行时间和 cpu 使用情况 - 您可能会发现,例如 8 个线程,使用的总 CPU 是 1/当前使用量的十分之一,但仍能在原始时间的 110-150% 内完成工作。这肯定是锁定争用正在扼杀您的 CPU 使用。
很多不同的东西:
- CPU查询计划的时间和执行器中查询执行的逻辑
- 将元组的文本表示形式转换为其磁盘格式。解析日期等。
- 日志输出
- 正在处理事务日志
- 插入要写入的页面时正在写入 shared_buffers,扫描 shard_buffers 以查找要写入的页面
- 用于锁管理的进程间通信
- 在检查唯一性、在索引中插入新键等时扫描内存中缓存的索引副本
- .....
如果您真的想知道有趣的细节,请启动 perf
并启用堆栈跟踪以查看 CPU 时间花在哪里。