SQL查询-使用replace函数速度较慢
我有一个查询需要很长时间,请参见下面SQL查询-使用replace函数速度较慢,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个查询需要很长时间,请参见下面 SELECT R.Email ,MAX(R.Id) ,MAX(R.Postcode) FROM ParsedCandidates PC INNER JOIN Results R ON REPLACE( REPLACE( REPLACE( REPLACE(R.[Resume], 'D:\documents\', '')
SELECT R.Email
,MAX(R.Id)
,MAX(R.Postcode)
FROM ParsedCandidates PC
INNER JOIN Results R
ON REPLACE(
REPLACE(
REPLACE(
REPLACE(R.[Resume], 'D:\documents\', '')
,'D:\CMT\Resumes\', '')
, 'internal_', '')
, 'monster_', '')
= REPLACE(
REPLACE(
REPLACE(
REPLACE(PC.[File], 'D:\documents\', '')
,'D:\CMT\Resumes\', '')
,'internal_', '')
, 'monster_', '')
WHERE CONTAINS(PC.ParsedCV, '"Marketing Executive"')
AND R.Email IS NOT NULL
AND R.Email <> ''
AND R.Postcode IS NOT NULL
AND R.Postcode <> ''
AND EXISTS (SELECT 1
FROM Candidates_Sourcing CS
WHERE CS.Email = R.Email
AND CS.Email IS NOT NULL
AND CS.Email <> ''
)
GROUP BY R.Email;
候选资源表和结果表都有很多很多行
我知道替换功能将导致可搜索性问题,但我需要这样做以确保匹配
任何关于如何改进的想法您所能做的就是在两个表上创建持久化列并对它们进行索引
ALTER TABLE Results ADD FixedPath AS REPLACE(
REPLACE(
REPLACE(
REPLACE([Resume], 'D:\documents\', '')
,'D:\CMT\Resumes\', '')
, 'internal_', '')
, 'monster_', '') PERSISTED
CREATE NONCLUSTERED INDEX ixResults_FixedPath ON Results (FixedPath) INCLUDE (...) WHERE (...)
包含索引,并且索引的位置可能取决于您的查询
如果不想更改表,可以在这两个表上创建索引视图,然后连接视图
CREATE VIEW v_Results
WITH SCHEMABINDING
AS
SELECT R.Id
-- , ... other columns ...
, REPLACE(
REPLACE(
REPLACE(
REPLACE(R.[Resume], 'D:\documents\', '')
,'D:\CMT\Resumes\', '')
, 'internal_', '')
, 'monster_', '') AS FixedPath
FROM dbo.Resume R
WHERE R.Email IS NOT NULL
AND R.Email <> ''
AND R.Postcode IS NOT NULL
AND R.Postcode <> ''
GO
创建了这两个视图之后,就可以合并了
SELECT ...
FROM v_Results R WITH (NOEXPAND)
JOIN v_ParsedCandidates PC WITH (NOEXPAND)
ON R.FixedPath = PC.FixedPath
NOEXPAND提示阻止SQL Server将视图扩展到基础查询中 如果REPLACE使查询不可搜索,那么数据引擎必须对整个表执行扫描。我猜您是在使用REPLACE函数删除路径并返回文件名?如果是这样的话,你真的应该把文件名作为一条单独的信息来存储;可以作为持久化计算列,也可以将路径和文件名存储为单独的列,然后进行适当的索引。然后您可以简单地使用一个类似R.ResumeFileName=PC.FileName的子句。计算机列是否意味着它可以被索引?做替换的费用会不会被转移到计算列,而且仍然很昂贵?为什么我说的是持久化计算列。它们可以被索引,顾名思义,该值作为持久值存储在表中。@MatthewStott是的-它正在移动成本。但是,您可以在插入/更新列时点击,也可以在每次运行此查询时点击。随着时间的推移,你认为哪一个更昂贵?再加上@SMor的观察,你不仅仅是在转移工作量,而是在将工作量分成小块。在执行查询期间,每次插入都会发生一行的替换工作,而不是同时发生数千或数百万次。将其视为一种分而治之的方法,而不是简单的提升和转移。
SELECT ...
FROM v_Results R WITH (NOEXPAND)
JOIN v_ParsedCandidates PC WITH (NOEXPAND)
ON R.FixedPath = PC.FixedPath