更新 vs 计数 vs 查询性能

7

请问这个说法是真还是假

这些查询的性能表现

SELECT * FROM table;

UPDATE table SET field = 1;

SELECT COUNT(*) FROM table;

它们是相同的吗?

还是有一种情况会导致它们的性能差异很大吗?

更新

  1. 我更想知道SELECT和UPDATE之间是否存在很大的差异。如果您愿意,可以忽略COUNT(*)。
  2. 假设选择执行全表扫描。更新也将对表中的所有行执行更新。
  3. 假设更新仅更新一个字段 - 尽管它将更新所有行(它是一个索引字段)
  4. 我知道它们需要不同的时间且执行不同的操作。我想知道的是差异是否显著。例如,如果更新需要比选择长5倍,则这是显着的。请使用此作为阈值。不需要精确。只需给出一个近似值即可。
5个回答

10

涉及不同类型的资源:

  • 磁盘 I/O (这是每个 DBMS 最昂贵的部分)
  • 缓冲区压力:获取一行将导致从磁盘获取一个页面,这需要缓冲器存储
  • 用于中间表、结构和聚合的工作/临时内存。
  • 面向前端进程的“终端”I/O。
  • 锁定、串行化、版本控制和日志记录的成本
  • CPU 成本:在大多数情况下可以忽略不计(与磁盘 I/O 相比)

问题中的UPDATE查询最难: 它将导致表的所有磁盘页面被提取,放入缓冲区,改变为新缓冲区并写回磁盘。在正常情况下,它还会导致其他进程被锁定,产生争用甚至更多的缓冲区压力。

SELECT *查询也需要所有页面; 它需要将它们全部转换/格式化为前端格式并发送回前端。

SELECT COUNT(*)是所有资源中最便宜的。在最坏的情况下,所有磁盘页都必须被提取。如果存在索引,则需要较少的磁盘I/O和缓冲器。CPU成本仍然可以忽略不计(在我看来),而“终端”输出是微不足道的。


你认为UPDATE会比SELECT *快5倍吗? - pillarOfLight
这要看情况。每个涉及的资源都是最终“公式”中的一个维度。而且每个维度都需要一个权重因子来形成类似于“x = c * y”的公式。换句话说:你的结果可能会有所不同。此外,还会对其他非相关查询和进程产生一定的影响(主要是缓冲区、内存和锁方面)。 - wildplasser
更新可能没有限制。由于更新语句中没有“ORDER BY”子句,因此没有顺序。限制UPDATE语句的唯一方法是使用WHERE子句:“UPDATE personel SET salary = salary * 1.5 WHERE gender ='f';”。 - wildplasser
不是真的,我刚试了一下,它可以工作。更新guinea_pig设置something = 3限制1;只有第一行被更新了。 - pillarOfLight
“第一行”是什么意思,这取决于月相吗?也许MySQL是不确定的?(锤子,螺丝刀) - wildplasser
显示剩余2条评论

7
当你说“性能”时,是指“它们执行所需的时间”吗?
  • 其中一个返回所有行中的所有数据。
  • 其中一个(如果删除“FROM”)会将数据写入行。
  • 一个在计算行数并返回行中的任何数据。
这三个查询都在执行完全不同的操作。因此,可以合理地得出结论,这三个查询完成所需的时间将不同。
最重要的是,你为什么要问这个问题?你想解决什么问题?我有一种不好的感觉,你正在走上一条错误的道路。

2

我在工作中有一张较大的(已经建立了索引)表格,以下是我发现的:

从X表格中选择所有内容(限制前10万条记录)(用时12.5秒)

从X表格中选择所有内容的数量(返回数百万条记录)(用时15.57秒)

对于一个已经建立了索引的表格,更新非常快(小于1秒)


1
SELECT 和 UPDATE 应该差不多(但这取决于数据库,可能会有所不同)。在许多数据库中,COUNT(*) 会被缓存,因此该查询很容易是 O(1)。当然,UPDATE 的懒惰实现也可以是 O(1),但我目前不知道有人这样做。简而言之,“错误”或“这取决于情况”。

1

这三个查询的作用完全不同。

它们各自具有其性能特征,不能直接进行比较。

您能澄清一下您试图调查什么吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接