简体   繁体   English

大表上的简单 UPDATE 查询性能不佳

[英]simple UPDATE query on large table has bad performance

I need to do the following update query through a stored procedure:我需要通过存储过程执行以下更新查询:

UPDATE table1
SET name = @name (this is the stored procedure inputparameter)
WHERE name IS NULL

Table1 has no indexes or keys, 5 columns which are 4 integers and 1 varchar (updatable column 'name' is the varchar column)表 1 没有索引或键,5 列是 4 个整数和 1 个 varchar(可更新列 'name' 是 varchar 列)

The NULL records are about 15.000.000 rows that need updating. NULL 记录大约有 15.000.000 行需要更新。 This takes about 50 minutes, which I think is too long.这大约需要 50 分钟,我认为这太长了。

I'm running an Azure SQL DB Standard S6 (400DTU's).我正在运行 Azure SQL DB 标准 S6(400DTU)。

Can anyone give me an advise to improve performance?任何人都可以给我建议以提高性能吗?

As you don't have any keys, or indexes, I can suggest following approach. 由于您没有任何密钥或索引,我可以建议以下方法。

1- Create a new table using INTO (which will copy the data) like following query. 1-使用INTO (将复制数据)创建一个新表,如下面的查询。

  SELECT 
       CASE 
              WHEN NAME IS NULL THEN @name 
              ELSE NAME 
       END AS NAME, 
       <other columns > 
INTO   dbo.newtable
FROM table1

2- Drop the old table 2-放下旧桌子

drop table table1

3- Rename the new table to table1 3-将新表重命名为table1

exec sp_rename 'dbo.newtable', 'table1'

Another approach can be using batch update, sometime you get better performance compared to bulk update (You need to test by adjusting the batch size). 另一种方法可以是使用批量更新,有时与批量更新相比,您可以获得更好的性能(您需要通过调整批量大小进行测试)。

WHILE EXISTS (SELECT 1 FROM table1 WHERE name is null)
BEGIN
    UPDATE TOP (10000) table1
    SET name = @name
    WHERE n ame is null
END

All you need is an INDEX via 您只需要一个INDEX via

       Create INDEX I1 ON table1(P_key)

And, then run your update query. 然后,运行您的更新查询。 This will help in fast data retrieval and updation of records on basis of some unique/key column made as an index in your existing table. 这将有助于基于作为现有表中索引的某些唯一/键列快速检索和更新记录。

can you do with following method ? 你能用以下方法吗?

UPDATE table1
SET name = ISNULL(name,@name)

for null values it will update with @name and rest will be updated with same value. 对于null值,它将使用@name更新,rest将使用相同的值进行更新。

No. You are updating 15,000,000 rows which is going to take a long time. 不。您要更新15,000,000行,这需要很长时间。 Each update has overhead for finding the row and logging the value. 每次更新都有查找行和记录值的开销。

With so many rows to update, it is unlikely that the overhead is finding the rows. 有了这么多行要更新,开销就不太可能找到行。 If you add an index on name , the update is going to actually have to update the index as well as updating the original values. 如果在name上添加索引,则更新实际上必须更新索引以及更新原始值。

If your concern is locking the database, you can set up a loop where you do something like this over and over: 如果你担心锁定数据库,你可以设置一个循环,你可以反复执行这样的操作:

UPDATE TOP (100000) table1
    SET name = @name (this is the stored procedure inputparameter)
    WHERE name IS NULL;

100,000 rows should be about 30 seconds or so. 100,000行应约为30秒左右。

In this case, an index on name does help. 在这种情况下, name 的索引确实有帮助。 Otherwise, each iteration of the loop would in essence be reading the entire table. 否则,循环的每次迭代本质上都是读取整个表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM