我有以下SQL Server存储过程:
ALTER PROCEDURE [dbo].[stg_GetFileDetails]
@file_name AS NVARCHAR(255),
@remove_dots AS BIT
AS
BEGIN
SET NOCOUNT ON;
IF (@remove_dots = 1)
BEGIN
SELECT
o.r_object_id,
'' AS [DAP ID],
p.nhs_patientid AS [MRN],
p.nhs_firstname AS [First Name],
p.nhs_surname AS [Surname],
o.object_name AS [File Name]
FROM
dm_sysobject_s o
INNER JOIN
nhs_instance_audit_s a ON o.r_object_id = a.r_object_id
INNER JOIN
nhs_patient_document_s d ON d.r_object_id = a.dia_edms_document_id
INNER JOIN
nhs_patient_s p ON d.nhs_patdoc_patientid = p.nhs_patientid
WHERE
[dbo].[No_dots_filename](o.object_name) = @file_name
END
ELSE
BEGIN
SELECT
o.r_object_id,
'' AS [DAP ID],
p.nhs_patientid AS [MRN],
p.nhs_firstname AS [First Name],
p.nhs_surname AS [Surname],
o.object_name AS [File Name]
FROM
dm_sysobject_s o
INNER JOIN
nhs_instance_audit_s a ON o.r_object_id = a.r_object_id
INNER JOIN
nhs_patient_document_s d ON d.r_object_id = a.dia_edms_document_id
INNER JOIN
nhs_patient_s p ON d.nhs_patdoc_patientid = p.nhs_patientid
WHERE
o.object_name = @file_name
END
现在,如果@remove_dots
为false,则此方法正常,但如果为true则调用以下函数:
ALTER FUNCTION [dbo].[No_dots_filename]
(@file_name AS NVARCHAR(255))
RETURNS NVARCHAR(255)
AS
BEGIN
DECLARE @revised_filename AS NVARCHAR(255)
DECLARE @ext AS NVARCHAR(5)
IF (LEN(@file_name) > 4)
BEGIN
-- see if the extension is a traditional 3 character one
IF SUBSTRING(@file_name, LEN(@file_name) - 4, 1) = '.'
BEGIN
SET @ext = RIGHT(@file_name, 4)
END
ELSE -- otherwise it might be one of the 4 character extensions like .docx
BEGIN
SET @ext = RIGHT(@file_name, 5)
END
-- remove dots from the main filename and then replace the extension
SET @revised_filename = REPLACE(LEFT(@file_name, LEN(@file_name) - LEN(@ext)), '.', '') + @ext
END
ELSE
BEGIN
SET @revised_filename = @file_name
END
RETURN @revised_filename
END
存储过程会冻结,或者至少花费很长时间才会产生差异。
有关如何更好地编码的任何建议吗?
答案 0 :(得分:0)
有几种资源可以避免在WHERE
条件的左侧有一个函数,这完全是因为它会导致非常糟糕的性能。
您的函数正在针对整个结果集中的每一行执行,这导致了您的问题。
其中一项资源是Common SQL Server Mistakes – Functions in the WHERE Clause。
避免这种情况的一种方法是将您的功能转换为table-valued
并将其交叉应用。