То, что написал @ lad2025, это путь.Тем не менее, в тех случаях, когда вычисляемый / сохраняемый столбец не является вариантом, вам будет полезно превратить ваш скалярный udf в встроенную табличную функцию (itvf).itvf работает намного лучше, чем пользовательские скалярные функции (scalar udf) по ряду причин, включая тот факт, что они не убивают параллелизм, как скалярные функции.
Вы можете переписать ваш скалярный udf как itvf, например:
CREATE FUNCTION dbo.itvfReplaceUrlEscapeChars(@MyString as varchar(Max))
RETURNS TABLE AS RETURN
SELECT
CASE WHEN @MyString LIKE '%[^0-9a-zA-Z\s-]%'
THEN LTRIM(RTRIM(
Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(
Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(
@MyString,'<','-'),'>','-'),'#','-'),'{','-'),'}','-'),'|','-'),'\','-')
,'^','-'),'~','-'),'[','-'),']','-'),';','-'),':','-'),'@','-'),'&','-')
,'$','-'),'/','-'),'.','-')))
ELSE LTRIM(RTRIM(@MyString))
END AS cleanedString;
GO
Тогда вы бы назвали это так:
CREATE PROC dbo.GetYearsByMake @Make VARCHAR(50)
AS
BEGIN
SELECT DISTINCT [year]
FROM make_model
CROSS APPLY dbo.itvfReplaceUrlEscapeChars(make)
WHERE active=1 AND isUnique=1
AND cleanedString = @Make
ORDER BY [year] DESC;
END
Стоит также отметить, что работас типами данных varchar (max) это очень дорого.Если вам удастся избежать использования varchar (8000) или менее, вы также увидите значительное повышение производительности.Иметь отфильтрованный некластеризованный индекс для make_model, который выглядит примерно так, вероятно, тоже поможет:
CREATE NONCLUSTERED INDEX nc_make_model_poc ON make_model(year)
WHERE active = 1 AND isUnique = 1;