数据库中的 CPU 利用率实际上意味着啥?

Posted

技术标签:

【中文标题】数据库中的 CPU 利用率实际上意味着啥?【英文标题】:What does CPU utilisation in databases actually mean?数据库中的 CPU 利用率实际上意味着什么? 【发布时间】:2015-09-29 15:01:37 【问题描述】:

我运行了两种查询,

1. 特意引入的查询以在大约 10 列中执行排序(排序依据)。这使用 CPU,因为排序是 CPU 密集型操作。

该场景涉及运行查询,该查询耗时 30 秒,并在 100 个不同的表上运行了大约 100 个查询。在 32 核计算机上,所有 32 个内核的 CPU 使用率约为 85%,所有 100 个查询并行运行。

2.在表上插入一百万行。

我不明白为什么这会消耗 CPU,因为这纯粹是磁盘 I/O。但是我使用 100 个同时连接/线程在单个表上插入了 100 万行,并且这些表上没有索引,现在插入不是加载数据的最快方式,但这里的重点是它在大约 10 个内核上消耗大约 32% 的 CPU 时间。这比上面的要少,但我仍然只是好奇。

我可能是错的,因为 Wal 存档已打开并且查询日志已打开 - 这是否对 CPU 有贡献。我假设没有,因为这些也是磁盘 IO。

除了 postgres 之外,这台机器上没有其他进程/应用程序正在运行/安装。

【问题讨论】:

反对者:想发表评论吗? 为什么要使用多线程插入?为了表现?你可以阅读***.com/questions/758945/… 我不明白为什么你会认为将数据写入数据库表是一个纯粹的磁盘 i/o 过程。必须记录每个更改,必须修改块,必须保留更改以防操作需要回滚。这不仅仅是将数据从一个文件复制到另一个文件。 好吧,我的假设是纯磁盘 I/O,但我有点怀疑自己,因此提出了问题。当然,这不仅仅是复制粘贴,而是会消耗更多 CPU 的东西,它是否可以被调整/控制。 【参考方案1】:

许多不同的东西:

查询计划的 CPU 时间和执行器中用于查询执行的逻辑 将元组的文本表示形式转换为它们的磁盘格式。解析日期等等。 日志输出 处理事务日志 在插入要写入的页面时写入 shared_buffers,扫描 shard_buffers 以查找要写出的页面 锁管理的进程间通信 在检查唯一性、在索引中插入新键等时扫描内存中缓存的索引副本 ....

如果您真的想知道详细信息,请启动 perf 并启用堆栈跟踪以查看 CPU 时间花费在哪里。

【讨论】:

【参考方案2】:

如果您的表有一个主键,那么它就有一个隐式索引。

如果表有一个主键,那么它会被存储为一个 b-tree 而不是一个简单的平面表,这也可能是真的;我不清楚这一点,因为多年来我的 postgres-fu 已经减弱,但是许多 DBMS 使用主键作为 b-tree 的默认集群键,并将所有内容存储在 b-tree 中。管理该 b 树需要大量 CPU。

此外,如果您从 100 个线程和连接中插入,则 postgres 必须执行锁定以保持内部数据结构一致。争夺锁会消耗大量 CPU,而且在具有多个 CPU 的机器上尤其难以高效执行 - 获取单个互斥锁需要系统 ala 缓存一致性协议中的每个 CPU 的协作。

您可能想试验不同数量的线程,同时测量总体运行时间和 CPU 使用率 - 您可能会发现,如果使用 8 个线程,总 CPU 使用量是您当前使用量的 1/10,但仍会得到工作在原始时间的 110-150% 内完成。这肯定表明锁争用正在扼杀您的 CPU 使用率。

【讨论】:

表上没有主键/索引,所以我猜它与锁定部分有关,感谢您提供的信息,我尝试更多并返回这里。 PostgreSQL 不按主键对表进行聚类。主键由单独的索引支持。

以上是关于数据库中的 CPU 利用率实际上意味着啥?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle内存和CPU占用率极高,是啥问题

top和ps aux得到cpu使用率的区别

PRIMARY KEY 实际上意味着啥,我的桌子需要一个吗?

dotnet core webservice中的CPU使用率逐渐增加

centos7 中的hosteye是啥进程?

浅谈Spark应用程序的性能调优