Faça as seguintes consultas:
DECLARE @X VARCHAR(200) = '1,2,3,4'
SELECT
*,
dbo.aUserDefinedScalarFunction(4) AS ScalarValue
FROM
MyTable T
INNER JOIN dbo.aUserDefineTableFunction(@X) A ON T.SomeID=A.SomeID
WHERE
(T.ID1 IS NULL OR T.ID1 IN (SELECT [value] FROM STRING_SPLIT(@X,',')))
AND
(T.ID2 IS NULL OR T.ID2 IN (SELECT Value FROM dbo.MySplitterFunction(@X))
Normalmente crio #tempTables indexadas para as WHERE
condições acima, descobri que para ter um desempenho melhor em grandes conjuntos de dados. No entanto, ainda não consigo encontrar respostas definitivas para as seguintes perguntas:
O analisador de consultas otimizará aUserDefinedScalarFunction(4) como ScalarValue ou será avaliado para cada registro?
O INNER JOIN dbo.aUserDefineTableFunction(@X) será materializado em uma tabela temporária uma vez ou será executado para cada registro? A função retorna table (não uma variável de tabela).
O resultado de SELECT [value] FROM STRING_SPLIT(@X,',') é otimizado ou é avaliado para cada comparação?
O resultado de SELECT Value FROM dbo.MySplitterFunction(@X) é otimizado ou é avaliado durante cada comparação?
Isso depende da função. Para uma função determinística especificada com schemabinding , o otimizador geralmente poderá avaliar seu resultado apenas uma vez, armazenando a resposta em cache.
Para detalhes, consulte:
As funções com valor de tabela inline são expandidas no texto da consulta de chamada antes da otimização, portanto, não há oportunidade especial para avaliação e armazenamento em cache antecipados. Isso não significa que o plano de execução não apresentará otimizações de cache e reutilização. Onde aplicável, o otimizador irá considerá-los (por exemplo, um spool) exatamente como faria para uma consulta sem uma função embutida.
Geralmente, o otimizador será capaz de dizer que
SPLIT_STRING
em uma entrada constante retorna resultados determinísticos. É provável que o plano avalie a divisão apenas uma vez, mas depende da forma do plano.Assumindo que a função divisora é uma função com valor de tabela de várias instruções, é muito provável que o resultado seja avaliado uma vez. Para obter detalhes e como saber se o armazenamento em cache ocorre a partir do plano de execução, consulte:
Tudo isso dito, você está certo em ser cauteloso sobre tudo isso. O otimizador frequentemente poderá avaliar expressões uma vez e reutilizar o resultado, mas isso não é garantido e geralmente requer análise especializada para determinar.
Forçar a materialização usando tabelas temporárias é frequentemente a solução mais robusta, pois garante uma determinada ordem e número de avaliações.
Cada linha avaliará as funções na cláusula where. Pesquise a consulta SARGABLE. https://www.sqlshack.com/how-to-use-sargable-expressions-in-t-sql-queries-performance-advantages-and-examples/