Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Aplica-se a:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Base de dados SQL no Microsoft Fabric
Quando você analisa o código T-SQL em seu projeto de banco de dados, um ou mais avisos podem ser categorizados como problemas de desempenho. Você deve resolver um problema de desempenho para evitar a seguinte situação:
- Uma verificação de tabela ocorre quando o código é executado.
Em geral, você pode suprimir um problema de desempenho se a tabela contiver tão poucos dados que uma verificação não fará com que o desempenho caia significativamente.
As regras fornecidas identificam os seguintes problemas de desempenho:
- SR0004: Evite usar colunas que não tenham índices como expressões de teste em predicados IN
- SR0005: Evite usar padrões que comecem com "%" em predicados LIKE
- SR0006: Mover uma referência de coluna para um lado de um operador de comparação para usar um índice de coluna
- SR0007: Use ISNULL(column, default_value) em colunas nulas em expressões
- SR0015: Extrair chamadas de função determinística de predicados WHERE
SR0004: Evite usar colunas que não tenham índices como expressões de teste em predicados IN
Se usar uma cláusula WHERE que faz referência a uma ou mais colunas que não estão indexadas como parte de um predicado IN, você causa uma varredura de tabela. A verificação de tabela reduz o desempenho.
Como corrigir violações
Para resolver esse problema, você deve fazer uma das seguintes alterações:
- Altere o predicado IN para fazer referência apenas às colunas que têm um índice.
- Adicione um índice a qualquer coluna à qual o predicado IN faça referência e que ainda não tenha um índice.
Example
Neste exemplo, uma instrução SELECT simples faz referência a uma coluna, [c1], que não tinha um índice. A segunda instrução define um índice que você pode adicionar para resolver esse aviso.
CREATE PROCEDURE [dbo].[Procedure3WithWarnings]
AS
SELECT [Comment]
FROM [dbo].[Table2]
WHERE [c1] IN (1, 2, 3)
CREATE INDEX [IX_Table2_C1]
ON [dbo].[Table2] (c1);
SR0005: Evite usar padrões que comecem com "%" em predicados LIKE
Você pode causar uma varredura de tabela se usar uma cláusula WHERE que contenha um predicado LIKE, como '%pattern string' para procurar texto que possa ocorrer em qualquer parte de uma coluna.
Como corrigir violações
Para resolver esse problema, você deve alterar a cadeia de caracteres de pesquisa para que ela comece com um caractere que não seja um curinga (%) ou você deve criar um índice de texto completo.
Example
No primeiro exemplo, a instrução SELECT causa uma verificação de tabela porque a cadeia de caracteres de pesquisa começa com um caractere curinga. No segundo exemplo, a instrução causa uma busca de índice porque a cadeia de caracteres de pesquisa não começa com um caractere curinga. Uma busca de índice recupera apenas as linhas que correspondem à cláusula WHERE.
SELECT [dbo].[Table2].[ID], [dbo].[Table2].[c1], [dbo].[Table2].[c2], [dbo].[Table2].[c3], [dbo].[Table2].[Comment]
FROM dbo.[Table2]
WHERE Comment LIKE '%pples'
SELECT [dbo].[Table2].[ID], [dbo].[Table2].[c1], [dbo].[Table2].[c2], [dbo].[Table2].[c3], [dbo].[Table2].[Comment]
FROM dbo.[Table2]
WHERE Comment LIKE 'A%'
SR0006: Mover uma referência de coluna para um lado de um operador de comparação para usar um índice de coluna
O seu código pode provocar uma varredura na tabela se comparar uma expressão que contenha uma referência a uma coluna.
Como corrigir violações
Para resolver esse problema, você deve retrabalhar a comparação para que a referência de coluna apareça sozinha em um lado do operador de comparação, em vez de dentro de uma expressão. Quando você executa o código que tem a referência de coluna sozinha em um lado do operador de comparação, o SQL Server pode usar o índice de coluna e nenhuma verificação de tabela é executada.
Example
No primeiro procedimento, uma cláusula WHERE inclui a coluna [c1] numa expressão como parte de uma comparação. No segundo procedimento, os resultados da comparação são idênticos, mas nunca requerem uma verificação de tabela.
CREATE PROCEDURE [dbo].[Procedure3WithWarnings]
@param1 int
AS
SELECT [c1], [c2], [c3], [Comment]
FROM [dbo].[Table2]
WHERE ([c1] + 5 > @param1)
CREATE PROCEDURE [dbo].[Procedure3Fixed]
@param1 int
AS
SELECT [c1], [c2], [c3], [Comment]
FROM [dbo].[Table2]
WHERE ([c1] > (@param1 - 5))
SR0007: Utilize ISNULL(coluna, valor_por_defeito) em colunas anuláveis nas expressões
Se o código comparar dois NULL valores ou um NULL valor com qualquer outro valor, o código retornará um resultado desconhecido.
Como corrigir violações
Você deve indicar explicitamente como os valores NULL devem ser manipulados em expressões de comparação, envolvendo cada coluna que possa conter um valor NULL numa função ISNULL.
Example
Este exemplo mostra uma definição de tabela simples e dois procedimentos armazenados. A tabela contém uma coluna, c2, que pode conter um NULL valor. O primeiro procedimento, ProcedureWithWarning, compara c2 a um valor constante. O segundo procedimento corrige o problema empacotando c2 com uma chamada para a ISNULL função.
CREATE TABLE [dbo].[Table1]
(
[ID] INT NOT NULL IDENTITY(0, 1),
[c1] INT NOT NULL PRIMARY KEY,
[c2] INT
)
ON [PRIMARY]
CREATE PROCEDURE [dbo].[ProcedureWithWarning]
AS
BEGIN
SELECT COUNT(*) FROM [dbo].[Table1]
WHERE [c2] > 2;
END
CREATE PROCEDURE [dbo].[ProcedureFixed]
AS
BEGIN
SELECT COUNT(*) FROM [dbo].[Table1]
WHERE ISNULL([c2],0) > 2;
END
SR0015: Extrair chamadas de funções determinísticas de predicados WHERE
Em um predicado WHERE, uma chamada de função é determinística se seu valor não depender dos dados selecionados. Essas chamadas podem causar verificações de tabela desnecessárias, o que diminui o desempenho do banco de dados.
Como corrigir violações
Para resolver esse problema, você pode atribuir o resultado da chamada a uma variável que você usa no predicado WHERE.
Example
No primeiro exemplo, o procedimento armazenado inclui uma chamada de função determinística, ABS(@param1), no predicado WHERE. No segundo exemplo, uma variável temporária contém o resultado da chamada.
CREATE PROCEDURE [dbo].[Procedure2WithWarning]
@param1 INT = 0,
AS
BEGIN
SELECT [c1], [c2], [c3], [SmallString]
FROM [dbo].[Table1]
WHERE [c2] > ABS(@param1)
END
CREATE PROCEDURE [dbo].[Procedure2Fixed]
@param1 INT = 0,
AS
BEGIN
DECLARE @AbsOfParam1 INT
SET @AbsOfParam1 = ABS(@param1)
SELECT [c1], [c2], [c3], [SmallString]
FROM [dbo].[Table1]
WHERE [c2] > @AbsOfParam1
END