使用文本更新varchar列的最快方法

Kat*_*ers 5 t-sql sql-server string sql-server-2008

我在列中有以下内容:

MetaDataServe
-------------
MindWorks.Accounts
MindWorks.Transactions
MindWorks.Commissions
...
Run Code Online (Sandbox Code Playgroud)

我需要将这些列更新为以下形式:

MindWorks.Client.Accounts
Run Code Online (Sandbox Code Playgroud)

我最初想过使用字符串函数来更新它们(LEFT,SUBSTR等),但是有没有替代或更好的方法来更新列中的文本以插入文本?

我使用的是SQL Server 2008,无法使用CLR集成.

Ric*_*iwi 10

这是一个关于"最快"的问题,因此下面提供了时间安排

测试设置,表格> 100万行

create table MetaDataServe (id int identity primary key, vc varchar(max));

insert MetaDataServe values
('MindWorks.Accounts'),
('MindWorks.Transactions'),
('MindWorks.Commissions');

insert MetaDataServe
select vc
from MetaDataServe, master..spt_values a, master..spt_values b
where b.number between 1 and 30
-- (1090110 row(s) affected)
Run Code Online (Sandbox Code Playgroud)

Stuff vs Replace vs SubString

性能摘要 - STUFF> SUBSTRING> REPLACE

update MetaDataServe set vc = STUFF(vc, 9, 0, '.Client')
Run Code Online (Sandbox Code Playgroud)

SQL Server解析和编译时间:
CPU时间= 0 ms,已用时间= 3 ms.
表'MetaDataServe'.扫描计数1,逻辑读取55402,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.

SQL Server执行时间:
CPU时间= 10094 ms,已用时间= 10808女士.
CPU时间= 10250 ms,经过时间= 10896 ms.

(2次来自多次执行以显示可变性,它非常低,因此可以认为时间精确到3%以内)

update MetaDataServe set vc = REPLACE(vc, '.', '.Client.')
Run Code Online (Sandbox Code Playgroud)

SQL Server解析和编译时间:
CPU时间= 3毫秒,已用时间= 3毫秒.
表'MetaDataServe'.扫描计数1,逻辑读取55402,物理读取0,预读读取159,lob逻辑读取0,lob物理读取0,lob预读读取0.

SQL Server执行时间:
CPU时间= 20469 ms,已用时间= 21238女士.

update MetaDataServe set vc = 'MindWorks.Client.' + SUBSTRING(vc, 11, 100)
Run Code Online (Sandbox Code Playgroud)

SQL Server解析和编译时间:
CPU时间= 0 ms,经过时间= 1 ms.
表'MetaDataServe'.扫描计数1,逻辑读取55402,物理读取0,预读读取3,lob逻辑读取0,lob物理读取0,lob预读读取0.

SQL Server执行时间:
CPU时间= 11219 ms,已用时间= 12030女士.
CPU时间= 11531 ms,经过时间= 12148 ms.

固定号码与PATINDEX和CHARINDEX

(固定位置版本已在上面给出)
性能摘要 - 修复>(PATINDEX = CHARINDEX)
PATINDEX和CHARINDEX之间似乎没有实质性差异

update MetaDataServe set vc = STUFF(vc, PATINDEX('%.%',vc), 0, '.Client')
Run Code Online (Sandbox Code Playgroud)

SQL Server解析和编译时间:
CPU时间= 0毫秒,已用时间= 2毫秒.
表'MetaDataServe'.扫描计数1,逻辑读取55400,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.

SQL Server执行时间:
CPU时间= 15218 ms,已用时间= 16167女士.

update MetaDataServe set vc = STUFF(vc, CHARINDEX('.',vc), 0, '.Client')
Run Code Online (Sandbox Code Playgroud)

SQL Server解析和编译时间:
CPU时间= 0 ms,已用时间= 3 ms.
表'MetaDataServe'.扫描计数1,逻辑读取55402,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.

SQL Server执行时间:
CPU时间= 15469 ms,已用时间= 16353女士.

笔记:

  • 上面给出的所有更新语句都可以(根据您的需要调整一两个)
  • 在每次测试之前,将删除整个表并重新创建以防止缓存问题

小心!

尽管STUFF速度更快,但您可以进入棘手的情况.如果您的数据包含

"MindWorksNoDot"
Run Code Online (Sandbox Code Playgroud)

并且您使用更新

update MetaDataServe set vc = STUFF(vc, CHARINDEX('.',vc), 0, '.Client')
Run Code Online (Sandbox Code Playgroud)

你最终得到了NULL!因为当CHARINDEX找不到点时,STUFF的第二个参数为零(0)会导致整个字符串变为NULL.

最后的话

为了安全性和可靠性,鉴于它只比STUFF方法慢33%,我只需使用REPLACE语句,即

update MetaDataServe set vc = REPLACE(vc, '.', '.Client.')
Run Code Online (Sandbox Code Playgroud)