我有一个包含九个长文本字段的表(Data
)。它目前有100万条记录,并且正在增长,所以我想加快一点。将多个交叉应用合并为一个查询
我使用的一个表值正则表达式函数(master.dbo.RegExMatches
),以解析出从这些九个字段字并把那些到具有记录ID的表(DataWordFullMap
)(Id
在下面的例子中),字(wordtoadd
),列名(第一个查询中的DE87
,第二个中的DE150
)和列中的起始字符位置(MatchIndex
)。
功能master.dbo.RegExMatches
取参数regex, column name, options
。当前的设置必须为每个字段扫描一次表(每个字段位于单独的查询中),而不是在一次扫描中将该函数应用于九列中的每一列。
将这些CROSS APPLY
语句合并到一个查询中有效吗?也许可以通过在CROSS APPLY
结果中添加一个附加列来获得正则表达式函数中使用的列的名称?其中一些列主要是NULL
,其他一些没有NULL
值,所以对9个分区中的每个分区进行全面扫描看起来很浪费,因为这些分区中的一些在大部分扫描中都没有结果。
下面的代码片段显示了两个涉及九个查询:
INSERT INTO DataWordFullMap
SELECT Id ,
CAST (Match AS nvarchar(255)) AS wordtoadd ,
'DE87' ,
MatchIndex
FROM
Data CROSS APPLY master.dbo.RegExMatches('[\w-[0-9ÿ_]]{2,}(-[\w-[0-9ÿ_]]{2,})?(''[\w-[0-9ÿ_]])?' , DE87 , master.dbo.RegExOptionEnumeration(0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0));
INSERT INTO DataWordFullMap
SELECT Id ,
CAST (Match AS nvarchar(255)) AS wordtoadd ,
'DE150' ,
MatchIndex
FROM
Data CROSS APPLY master.dbo.RegExMatches('[\w-[0-9ÿ_]]{2,}(-[\w-[0-9ÿ_]]{2,})?(''[\w-[0-9ÿ_]])?' , DE150 , master.dbo.RegExOptionEnumeration(0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0));
谢谢!这样可行。但是,当我比较原始版本和编辑版本时,我感到非常惊讶。原文耗时107秒,综合版耗时1046秒。当我查看服务器的性能监视器时,磁盘系统似乎受到了最大的打击(它使用SSD),写入以每秒110 MB的速度写入,其中数据库日志文件的写入速度为100 MB /秒。记忆似乎没有问题。数据库设置为简单恢复模式日志记录。 – rsjaffe
@RoryJaffe Ouch,这不好... –
@RoryJaffe我想知道整合版本的执行计划是什么样的。我没有安装这个'master.dbo.RegExOptionEnumeration',我没有样本数据,所以我不能说真正的原因。 –