UPDATE vs COUNT vs SELECT 性能
Posted
技术标签:
【中文标题】UPDATE vs COUNT vs SELECT 性能【英文标题】:UPDATE vs COUNT vs SELECT performance 【发布时间】:2013-10-18 20:30:41 【问题描述】:这句话是真是假
这些查询的性能
SELECT * FROM table;
UPDATE table SET field = 1;
SELECT COUNT(*) FROM table;
完全相同
或者有没有出现过一个人的表现会与另一个人有很大不同的情况?
更新
-
如果 SELECT 和 UPDATE 之间存在很大差异,我会更感兴趣。如果需要,您可以忽略 COUNT(*)
假设选择执行全表扫描。该更新还将对表中的所有行执行更新。
假设更新只更新一个字段 - 尽管它会更新所有行(它是一个索引字段)
我知道他们会花不同的时间做不同的事情。我想知道的是差异是否显着。例如。如果更新将花费比选择长 5 倍的时间,那么这很重要。以此为阈值。而且没有必要精确。只给出一个近似值。
【问题讨论】:
【参考方案1】:SELECT 和 UPDATE 应该大致相同(但它们很容易发生变化,这取决于数据库)。 COUNT(*) 缓存在许多数据库中,在某种程度上,因此查询很容易成为 O(1)。当然 UPDATE 的惰性实现也可能是 O(1),但我不知道目前有人这样做。
tl;dr:“假”或“视情况而定”。
【讨论】:
【参考方案2】:这三个查询做的事情截然不同。
它们都有自己的性能特点,不能直接比较。
您能澄清一下您要调查的内容吗?
【讨论】:
【参考方案3】:当您说“性能”时,您的意思是“执行它们需要多长时间”?
其中之一是返回所有行中的所有数据。 其中之一(如果您删除“FROM”)正在将数据写入行。 一种是对行进行计数,但不返回行中的任何数据。所有这三个查询都在做完全不同的事情。因此,可以合理地得出结论,它们三个都将花费不同的时间来完成。
最重要的是,你为什么要问这个问题?你想解决什么问题?我有一种不好的感觉,你问这个问题会走错路。
【讨论】:
【参考方案4】:我在工作中有一个大的(授予索引的)表,这就是我发现的
select * from X(限于前 100,000 条记录)(12.5 秒)
select count(*) from X(返回数百万条记录)(15.57 秒)
索引表的更新非常快(不到一秒)
【讨论】:
【参考方案5】:涉及不同的资源类型:
磁盘 I/O(这是每个 DBMS 中成本最高的部分) 缓冲压力:获取一行会导致从磁盘中获取页面,这将需要存储缓冲内存 用于中间表、结构和聚合的工作/临时内存。 “终端”I/O 到前端进程。 锁定、序列化、版本控制和日志记录的成本 CPU 成本:在大多数情况下可以忽略不计(与磁盘 I/O 相比)问题中的UPDATE
查询是最难的:它将导致表的所有 个磁盘页面被提取、放入缓冲区、更改为新 缓冲区并写回磁盘。正常情况下,还会导致其他进程被锁住,从而导致争用甚至更大的缓冲压力。
SELECT *
查询也需要所有页面;它需要将它们全部转换/格式化为前端格式并将它们发送回前端。
SELECT COUNT(*)
是所有资源中最便宜的。在最坏的情况下所有磁盘页面必须被获取。如果存在索引,则需要更少的磁盘 I/O 和缓冲区。 CPU 成本仍然可以忽略不计(恕我直言),“终端”输出是微不足道的。
【讨论】:
你认为 UPDATE 会比 SELECT * 大 5 倍吗? 视情况而定。涉及的每个资源都是最终公式中的一个维度。每个维度都需要一个权重因子来得出x = c * y
类型的公式。爱荷华州:YMMV。对其他不相关的查询和进程(主要是WRT缓冲区、内存和锁)也有一定的影响
如果我对更新执行 LIMIT 会怎样。这会显着减少花费的时间吗?例如,假设无限制地更新表中的所有 500000 行。将其设为 LIMIT 1(因此仅更新表中的 1 行)会减少执行查询所需的时间吗?
可能的更新没有限制。没有顺序,因为更新时没有ORDER BY
子句。限制 UPDATE 语句的唯一方法是使用 WHERE 子句:UPDATE personel SET salary = salary * 1.5 WHERE gender = 'f';
不是真的,我刚试过它有效 UPDATE guinea_pig SET something = 3 LIMIT 1;并且只有第一行得到了更新以上是关于UPDATE vs COUNT vs SELECT 性能的主要内容,如果未能解决你的问题,请参考以下文章
COUNT(*) vs. COUNT(1) vs. COUNT(pk):哪个更好? [复制]
MySQL中的limit vs exists vs count(*) vs count(id) [重复]