这是一个关于“最快”的问题,所以下面提供了时间
测试设置,超过 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)
Stuff vs Replace vs SubString
性能总结 - STUFF > SUBSTRING > REPLACE
update MetaDataServe set vc = STUFF(vc, 9, 0, '.Client')
SQL Server 解析和编译时间:
CPU 时间 = 0 毫秒,经过的时间 = 3 毫秒。
表“元数据服务”。扫描计数 1,逻辑读取 55402,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
SQL Server 执行时间:
CPU 时间 = 10094 毫秒,运行时间 = 10808 毫秒。
CPU 时间 = 10250 毫秒,经过时间 = 10896 毫秒。
(2次是多次执行,以显示变异性,非常低,可以认为时间准确到3%以内)
update MetaDataServe set vc = REPLACE(vc, '.', '.Client.')
SQL Server 解析和编译时间:
CPU 时间 = 3 毫秒,经过的时间 = 3 毫秒。
表“元数据服务”。扫描计数 1,逻辑读取 55402,物理读取 0,预读读取 159,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
SQL Server 执行时间:
CPU 时间 = 20469 毫秒,经过时间 = 21238 毫秒。
update MetaDataServe set vc = 'MindWorks.Client.' + SUBSTRING(vc, 11, 100)
SQL Server 解析和编译时间:
CPU 时间 = 0 毫秒,经过的时间 = 1 毫秒。
表“元数据服务”。扫描计数 1,逻辑读取 55402,物理读取 0,预读读取 3,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
SQL Server 执行时间:
CPU 时间 = 11219 毫秒,经过时间 = 12030 毫秒。
CPU 时间 = 11531 毫秒,经过时间 = 12148 毫秒。
固定数字 vs PATINDEX vs CHARINDEX
(上面已经给出了固定位置版本)
性能总结 - FIXED > (PATINDEX = CHARINDEX)
那里PATINDEX 和 CHARINDEX 之间似乎没有实质性区别
update MetaDataServe set vc = STUFF(vc, PATINDEX('%.%',vc), 0, '.Client')
SQL Server 解析和编译时间:
CPU 时间 = 0 毫秒,经过的时间 = 2 毫秒。
表“元数据服务”。扫描计数 1,逻辑读取 55400,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
SQL Server 执行时间:
CPU 时间 = 15218 毫秒,经过时间 = 16167 毫秒。
update MetaDataServe set vc = STUFF(vc, CHARINDEX('.',vc), 0, '.Client')
SQL Server 解析和编译时间:
CPU 时间 = 0 毫秒,经过的时间 = 3 毫秒。
表“元数据服务”。扫描计数 1,逻辑读取 55402,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
SQL Server 执行时间:
CPU 时间 = 15469 毫秒,经过时间 = 16353 毫秒。
注意事项:
- 根据您的需要,上面给出的所有更新语句都可以使用(需要一两次调整)
- 在每次测试之前,都会删除并重新创建整个表以防止出现缓存问题
注意!
即使 STUFF 速度更快,您也可能会遇到棘手的情况。如果您的数据包含
"MindWorksNoDot"
你更新使用
update MetaDataServe set vc = STUFF(vc, CHARINDEX('.',vc), 0, '.Client')
你最终得到 NULL!因为当 CHARINDEX 找不到点时,STUFF 的第二个参数为零 (0) 会导致整个字符串变为 NULL。
最后的话
为了安全性和可靠性,鉴于它仅比 STUFF 方法慢 33%,我会简单地使用 REPLACE 语句,即
update MetaDataServe set vc = REPLACE(vc, '.', '.Client.')