相关疑难解决方法(0)

更新所有列的开销是多少,即使是那些没有改变的列

在更新一行时,许多 ORM 工具发出一个 UPDATE 语句,设置与该特定实体关联的每一列

优点是您可以轻松地批量更新语句,因为UPDATE无论您更改什么实体属性,语句都是相同的。此外,您甚至还可以使用服务器端和客户端语句缓存。

所以,如果我加载一个实体并且只设置一个属性:

Post post = entityManager.find(Post.class, 1L);
post.setScore(12);
Run Code Online (Sandbox Code Playgroud)

所有列都将被更改:

UPDATE post
SET    score = 12,
       title = 'High-Performance Java Persistence'
WHERE  id = 1
Run Code Online (Sandbox Code Playgroud)

现在,假设我们也有一个关于该title属性的索引,数据库难道不应该意识到该值无论如何都没有改变吗?

这篇文章中,Markus Winand 说:

所有列的更新显示了我们在前几节中已经观察到的相同模式:响应时间随着索引的增加而增加。

我想知道为什么会有这种开销,因为数据库将关联的数据页从磁盘加载到内存中,因此它可以确定是否需要更改列值。

即使对于索引,它也不会重新平衡任何内容,因为对于未更改的列,索引值不会更改,但它们已包含在 UPDATE 中。

是不是和冗余不变列关联的B+树索引也需要导航,数据库才意识到叶子值还是一样的?

当然,一些 ORM 工具允许您只更新更改的属性:

UPDATE post
SET    score = 12,
WHERE  id = 1
Run Code Online (Sandbox Code Playgroud)

但是,当不同行的不同属性更改时,这种类型的 UPDATE 可能并不总是从批量更新或语句缓存中受益。

performance index orm update

19
推荐指数
2
解决办法
7732
查看次数

索引对更新列不在索引中的更新语句的影响

我经常看到人们说索引变慢了updatedelete并且insert。这被用作笼统的陈述,就好像它是绝对的一样。

在调整我的数据库以提高性能的同时,我不断遇到这种情况,这对我来说在逻辑上似乎与该规则相矛盾,而且我找不到任何人以其他方式说或解释。

在 SQL Server 中,我相信/假定大多数其他 DBMS,您的索引是根据您指定的特定列创建的。插入和删除总是会影响整行,因此它们不可能不影响索引,但更新似乎更独特一些,它们只能专门影响某些列。

如果我有未包含在任何索引中的列并且我更新它们,它们是否会因为我在该表中的其他列上有索引而变慢?

例如,在我的User表中,我有一个或两个索引,主键是 Identity/Auto Increment 列,另一个可能是某个外键列。
如果我直接更新一个没有索引的列,比如他们的电话号码或地址,这个更新是否会变慢,因为我在这两种情况下的其他列上都有索引?我正在更新的列不在索引中,所以从逻辑上讲,索引不应该更新,不是吗?如果有的话,我认为如果我在 WHERE 子句中使用索引,它们会加速。

performance index sql-server update query-performance

18
推荐指数
2
解决办法
4万
查看次数

使用xml参数插入多个数据时如何避免使用Merge查询?

我正在尝试使用一组值更新表。数组中的每一项都包含与 SQL Server 数据库表中的行匹配的信息。如果该行已存在于表中,我们将使用给定数组中的信息更新该行。否则,我们在表中插入一个新行。我已经基本上描述了 upsert。

现在,我试图在采用 XML 参数的存储过程中实现这一点。我使用 XML 而不是表值参数的原因是,执行后者时,我必须在 SQL 中创建自定义类型并将此类型与存储过程相关联。如果我以后更改了存储过程或数据库架构中的某些内容,则必须重做存储过程和自定义类型。我想避免这种情况。此外,TVP 相对于 XML 的优势对我的情况没有用,因为我的数据数组大小永远不会超过 1000。这意味着我不能使用这里提出的解决方案:How to insert multiple records using XML in SQL server 2008

此外,这里的类似讨论(UPSERT - 是否有更好的替代 MERGE 或 @@rowcount?)与我所问的不同,因为我试图将行插入到表中。

我希望我可以简单地使用以下一组查询来更新 xml 中的值。但这行不通。当输入是单行时,这种方法应该有效。

begin tran
   update table with (serializable) set select * from xml_param
   where key = @key

   if @@rowcount = 0
   begin
      insert table (key, ...) values (@key,..)
   end
commit tran
Run Code Online (Sandbox Code Playgroud)

下一个替代方法是使用详尽的 IF EXISTS 或其以下形式的变体之一。但是,我以次优效率为由拒绝了这一点:

IF (SELECT COUNT ... ) > 0 …
Run Code Online (Sandbox Code Playgroud)

xml sql-server stored-procedures t-sql upsert

11
推荐指数
1
解决办法
1万
查看次数