UPDATE ALL WHERE vs COUNT然后更新

时间:2015-01-09 13:45:04

标签: mysql sql

我们说我有一个带有已读/未读消息的收件箱系统。我想让邮件在打开后切换为未读。

每次打开邮件时, 最好使用指定unread = 1的WHERE子句检查消息是否未读取消息的主键上的COUNT查询,然后如果计数优于0,则更新该条目以将读取字段设置为1,

,或者

每次使用WHERE子句指定消息的主键并读取字段= 0时执行UPDATE查询

要明确,这样做是否更好

SELECT COUNT(*) FROM messages WHERE messages.id = 1 AND messages.read = 0
if (query_above > 0)
    UPDATE messages SET messages.read = 1 WHERE messages.id = 1

UPDATE messages SET messages.read = 1 WHERE messages.id = 1 AND messages.read = 0

在这种情况下,我不愿意找到更好的方法来做到这一点;在任意情况下,这是一个纯粹的表现问题。

2 个答案:

答案 0 :(得分:2)

单个查询更好。无论哪种方式,数据库引擎都必须通过它的表,您将节省将其报告回处理应用程序的开销,然后处理应用程序发送另一个查询请求以更改数据库引擎刚访问过的行(和现在必须再次查询)

答案 1 :(得分:0)

由于多种原因,单个查询更好。但首先,这个查询:

UPDATE messages
    SET messages.read = 1
    WHERE messages.id = 1 AND messages.read = 0;

可以使用messages(id, read)上的索引进行优化。如果read已经是桌面上的唯一或主要密钥,则id并非绝对必要。

为什么一个查询更好?首先,存在运行多个查询的问题。每个都有自己的开销,因此更少的查询更快。 count(*)存在一个更重要的问题,用于测试存在。 SQL引擎并不知道你只关心" 0"或者"大于0",所以它实际上必须计算一切。编写该查询的更好方法是使用exists

if exists (select 1 from messages where messages.id = 1 and messages.read = 0)
    UPDATE messages SET messages.read = 1 WHERE messages.id = 1

这将停在匹配的第一行并停止处理count()继续处理。

第三个原因是竞争条件。在多线程应用程序中,某些内容可能会在ifupdate之间发生变化。这是使用一个查询的最强原因。一个查询不仅更快,而且更正确。