我有一个正在处理的大表,几乎所有列都需要使用replace语句来删除单引号和双引号。代码如下所示:
SET QUOTED_IDENTIFIER ON
Update dbo.transactions set transaction_name1 = Replace(transaction_name1,'''','')
Update dbo.transactions set transaction_name2 = Replace(transaction_name2,'''','')
Update dbo.transactions set transaction_name3 = Replace(transaction_name3,'''','')
Update dbo.transactions set transaction_name4 = Replace(transaction_name4,'''','')
Update dbo.transactions set transaction_name5 = Replace(transaction_name5,'''','')
我没有在表上放置一个索引,因为我不确定哪个列有什么好处,我正在更新几乎所有的列。如果我按主键对表格进行排序会有助于提高性能吗?
那时语句已经运行了2个多小时没有错误消息,并且想知道是否有解决这个性能问题的解决方案,除了通常更多的硬件更改?如果有人可以就如何提高脚本性能提出建议。
干杯, 彼得
答案 0 :(得分:4)
您可以将其设为一个UPDATE语句:
UPDATE transactions SET
transaction_name1 = Replace(transaction_name1,'''',''),
transaction_name2 = Replace(transaction_name2,'''','')
... (and so on)
这可能会使性能提高近5倍。
编辑:
由于这是一个巨大的数据集(90MM行)上的一个镜头,我建议添加一个where子句并批量运行。
如果您的交易有主键,请在其上对更新进行分区,一次执行500k。
在具有显式事务的循环中执行此操作,以使日志使用保持最小:
DECLARE @BaseID INT, @BatchSize INT
SELECT @BaseID = MAX(YourKey), @BatchSize = 500000 FROM transactions
WHILE @BaseID > 0 BEGIN
PRINT 'Updating from ' + CAST(@BaseID AS VARCHAR(20))
-- perform update
UPDATE transactions SET
transaction_name1 = Replace(transaction_name1,'''',''),
transaction_name2 = Replace(transaction_name2,'''','')
-- ... (and so on)
WHERE YourKey BETWEEN @BaseID - @BatchSize AND @BaseID
SET @BaseID = @BaseID - @BatchSize - 1
END
另一个注意事项:
如果报价不得出现在您的数据中,您可以创建一个check constraint来阻止它们。这是最后的努力,因为任何尝试将它们放入的应用程序都需要处理数据库异常,但它将保持您的数据清洁。这样的事情可能会这样做:
ALTER TABLE transactions
ADD CONSTRAINT CK_NoQuotes CHECK(
CHARINDEX('''',transaction_name1)=0 AND
CHARINDEX('''',transaction_name2)=0 AND
-- and so on...
)
答案 1 :(得分:2)
您可以将这些语句组合起来,这可能会更快一些:
SET QUOTED_IDENTIFIER ON
UPDATE dbo.transactions
SET transaction_name1 = REPLACE(transaction_name1,'''',''),
transaction_name2 = REPLACE(transaction_name2,'''',''),
transaction_name3 = REPLACE(transaction_name3,'''',''),
transaction_name4 = REPLACE(transaction_name4,'''',''),
transaction_name5 = REPLACE(transaction_name5,'''','')
另外,查看估计的执行计划。 它可能会为您提供有关如何优化数据库/查询的有用建议(它是SQL Management Studio按钮栏中的一个小方块按钮)。
答案 2 :(得分:1)
您可能只尝试将其设为一个UPDATE并仅更新需要它的行:
UPDATE dbo.transactions
SET transaction_name1 = REPLACE(transaction_name1,'''',''),
transaction_name2 = REPLACE(transaction_name2,'''',''),
transaction_name3 = REPLACE(transaction_name3,'''',''),
transaction_name4 = REPLACE(transaction_name4,'''',''),
transaction_name5 = REPLACE(transaction_name5,'''','')
WHERE
CHARINDEX('''',transaction_name1)>0
OR CHARINDEX('''',transaction_name2)>0
OR CHARINDEX('''',transaction_name3)>0
OR CHARINDEX('''',transaction_name4)>0
OR CHARINDEX('''',transaction_name5)>0