Sql server 将多个交叉应用合并到一个查询中
我有一个表(Sql server 将多个交叉应用合并到一个查询中,sql-server,tsql,cross-apply,Sql Server,Tsql,Cross Apply,我有一个表(数据),其中包括九个长文本字段。它目前有1000000条记录,而且还在增长,所以我想加快速度 我正在使用一个表值正则表达式函数(master.dbo.RegExMatches)来解析这九个字段中的单词,并将它们放入一个表(DataWordFullMap),该表具有记录ID(ID,在下面的示例中),word(wordtoadd),列名(DE87在第一个查询中,DE150在第二个查询中)和列中的起始字符位置(MatchIndex) 函数master.dbo.RegExMatches采用参
数据
),其中包括九个长文本字段。它目前有1000000条记录,而且还在增长,所以我想加快速度
我正在使用一个表值正则表达式函数(master.dbo.RegExMatches
)来解析这九个字段中的单词,并将它们放入一个表(DataWordFullMap
),该表具有记录ID(ID
,在下面的示例中),word(wordtoadd
),列名(DE87
在第一个查询中,DE150
在第二个查询中)和列中的起始字符位置(MatchIndex
)
函数master.dbo.RegExMatches
采用参数regex、列名、选项
。当前设置必须为每个字段扫描一次表(每个字段在单独的查询中),而不是在一次扫描中将函数应用于九列中的每一列
有没有一种有效的方法将这些交叉应用
语句合并到一个查询中?也许可以通过在交叉应用
结果中添加一个列,该列具有regex函数中使用的列的名称?其中一些列大部分是NULL
,其他列没有NULL
值,因此看起来很浪费我要对这九个扫描中的每一个进行完整扫描,而其中的一些扫描在大部分扫描中都没有结果
以下代码段显示了涉及的九个查询中的两个:
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/秒用于数据库日志文件。内存似乎没有问题。数据库设置为简单恢复模式日志记录。@RoryJaffe我想知道合并版本的执行计划是什么样的。我还没有安装此
master.dbo.regexoptionnumeration
,我没有样本数据,因此我无法真正说明原因。为了制定执行计划,我决定设置DataWordFullMap表的副本,以避免覆盖好的数据。我将编辑后的版本作为insert运行到新表中,查询耗时108秒——合并查询与原始查询之间仅相差一秒。我不知道有什么不同。在运行查询之前,我在早期的测试中截断了DataWordFullMap,因此我认为这两种情况类似,但看起来不一样。执行计划与我第一次为早期测试整合查询时的执行计划相同。下面是对实际p的描述合并查询局域网:合并查询有9套TVF→计算机标量。与此并行的是数据表的聚集索引扫描。这些数据表在嵌套循环中连接,然后是计算标量,然后是表插入。然后是排序(有索引),然后是索引插入。计划显示大部分时间都花在排序上(成本66%)@RoryJaffe原始表格上的数据应该提供一些线索。分析这些数据并根据它给出的指示采取行动需要一些实践。此外,即使在完美的环境中,我认为合并版本也不会比单个语句运行得更快……工作量基本上是一样的。如果完成了工作,也没有多大关系在个别声明中。
INSERT INTO datawordfullmap(
-- ...
)
SELECT
d.id,
rems.wordtoadd
rems.cn,
rems.matchindex
FROM
data AS d
CROSS APPLY (
SELECT
cn='DE87',
wordtoadd=CAST(rem.match AS NVARCHAR(255)),
rem.matchindex
FROM
master.dbo.RegExMatches (
'[\w-[0-9ÿ_]]{2,}(-[\w-[0-9ÿ_]]{2,})?(''[\w-[0-9ÿ_]])?',
d.DE87,
master.dbo.RegExOptionEnumeration( 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 )
) AS rem
UNION ALL
SELECT
cn='DE150',
wordtoadd=CAST(rem.match AS NVARCHAR(255)),
rem.matchindex
FROM
master.dbo.RegExMatches (
'[\w-[0-9ÿ_]]{2,}(-[\w-[0-9ÿ_]]{2,})?(''[\w-[0-9ÿ_]])?',
d.DE150,
master.dbo.RegExOptionEnumeration( 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 )
) AS rem
-- UNION ALL
-- ...
) AS rems;