在单个查询中组合 2 个更新查询 - 性能

Posted

技术标签:

【中文标题】在单个查询中组合 2 个更新查询 - 性能【英文标题】:Combine 2 update querys in a single query - performance 【发布时间】:2019-04-17 14:14:50 【问题描述】:

我正在编写一个最喜欢的函数。

例如,我们有多个地址,可以选择一个作为收藏夹。

目前我有 2 个查询来完成这项工作:

UPDATE userdata
SET maindata = 0
WHERE 
cid = :id;

UPDATE userdata
SET maindata = 1
WHERE 
cid = :id AND id = :id2
LIMIT 1

在第一个查询中,我将所有地址设置为“不喜欢”,在第二个查询中,我将新选择的地址设置为最喜欢的。

有没有办法改进这个查询或将两者都重写为 1 ?甚至是更好的解决方案?

【问题讨论】:

你不应该尝试提高不慢的东西的性能。 UPDATE userdata SET maindata = (id = :id2) WHERE cid = :id 【参考方案1】:

如果您想要单个查询,您可以使用 case when(或 if)

update  userdata 
set maindate = case when id = :id2 then 1 
                else 0 end 
where  cid = :id;

为了提高性能,请确保您在 userdata 列(cid、id)上有正确的索引

第一个 wuary 扫描的行数应该相同..但是这样可以避免第二个 ..

最终尝试创建一个复合索引

 create index myidx1 on userdata(cid, id)

【讨论】:

感谢您的回答,它工作得很好,这样查询会表现得更好吗? 我用 Explain 检查了性能,看起来性能可能更差,因为必须检查表中的所有行,而不是用 2 个查询来检查这个用户只有这么多行,比如地址。如果表很大,最好使用 2 个查询然后使用案例 1。 @delato468 回答已更新.. 有一些建议 我在 id 上有一个主键,在 cid 上有一个索引,根据解释,涉及所有 5 个地址而不是 2 个。我认为问题是 case 函数比 where 子句更早执行 不,你需要一个复合索引,查询只能为每个表使用一个索引,所以..尝试在 userdata(cid, id) 上创建索引 myidx1 ..【参考方案2】:
UPDATE userdata SET maindata = (case when cid = id AND id = id2 then 1 else 0 end);

这会有所帮助。我不确定您的查询,但这会有所帮助。让我知道您是否看起来与众不同...

【讨论】:

cid = id 有点随机,而不是 OP 要求的。 :id:id2 是(命名的)占位符,如 ?,用于一些客户端,如 php-PDO。

以上是关于在单个查询中组合 2 个更新查询 - 性能的主要内容,如果未能解决你的问题,请参考以下文章

SQL 查询将多条记录中的值组合到单个列中

MySQL ----- 组合查询 UNION(十五)

MySQL ----- 组合查询 UNION(十五)

更新另一个组合框后的组合框重新查询

组合查询

Adwords 关键字报告在单个查询中返回与组合查询不同的数据