AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 9832
Accepted
Ryan Delucchi
Ryan Delucchi
Asked: 2010-07-02 15:11:16 +0800 CST2010-07-02 15:11:16 +0800 CST 2010-07-02 15:11:16 +0800 CST

Desempenho atingido usando CAST em T-SQL

  • 772

Temos um gerador SQL que emite instruções condicionais SQL genericamente para campos especificados (que, para fins de discussão: rotularemos como myField).

Se myFieldfor do tipo NVARCHAR, podemos fazer uma comparação do referido campo com uma string da seguinte forma: myField = 'foo'.

No entanto, isso não funciona para campos do tipo NTEXT. Assim, temos que fazer a comparação com um elenco: CAST(myField as NVARCHAR(MAX)) = 'foo'. Isso funcionará de fato se myFieldfor do tipo NVARCHARou NTEXT.

Qual é o impacto no desempenho de fazer a conversão mencionada em um campo que já é do tipo NVARCHAR? Minha esperança é que o SQL Server seja inteligente o suficiente para reconhecer dinamicamente que myFieldjá é do tipo NVARCHAR(transformando-o efetivamente CASTem um no-op).

sql-server performance
  • 3 3 respostas
  • 20961 Views

3 respostas

  • Voted
  1. Best Answer
    Martin Smith
    2010-07-02T15:25:13+08:002010-07-02T15:25:13+08:00

    Se a conversão da coluna for exatamente do mesmo tipo de dados e comprimento e o predicado de busca for literal, ele realmente parece desconsiderá-lo ou tratá-lo como não operacional e um índice busca por igualdade.

    Seek Keys[1]: Prefix: [tempdb].[dbo].[#test].name = Scalar Operator(N'rpc')
    

    Se a conversão da coluna for do mesmo tipo de dados, mas de comprimento maior, e o predicado de busca for uma cadeia de caracteres literal, isso causará uma varredura de índice. Isso obviamente deve ser evitado.

    Se a conversão da coluna for para o mesmo tipo de dados e o mesmo ou maior comprimento e o predicado de busca for uma variável local, ele adicionará um operador escalar de computação ao plano de execução. Isso chama GetRangeThroughConverte gera um intervalo.

    Este intervalo é usado para fazer uma busca de índice e parece bastante eficiente

    Seek Keys[1]: 
    Start: [tempdb].[dbo].[#test].name > Scalar Operator([Expr1006]), 
    End: [tempdb].[dbo].[#test].name < Scalar Operator([Expr1007])
    

    Código de teste

    SELECT *
     INTO #test
      FROM [master].[dbo].[spt_values]
    
    CREATE NONCLUSTERED INDEX [ixname] ON #test
    (
        [name] ASC
    )
    
    DECLARE @name NVARCHAR(MAX)
    
    SET @name = 'rpc'
    
    SELECT name
    FROM #test
    WHERE CAST(name AS NVARCHAR(35))= @name --Cast the same and local variable
    
    SELECT name
    FROM #test
    WHERE CAST(name AS NVARCHAR(MAX))=@name --Cast to longer and local variable
    
    SELECT name
    FROM #test
    WHERE CAST(name AS NVARCHAR(35))='rpc' --Cast the same and literal
    
    SELECT name
    FROM #test
    WHERE CAST(name AS NVARCHAR(MAX))='rpc' --Cast to longer and literal
    
    • 12
  2. gbn
    2010-07-02T21:25:50+08:002010-07-02T21:25:50+08:00

    Em geral, o CASTirá matar o desempenho porque invalida qualquer uso de busca de índice, como mostra o último exemplo de Martin Smith. A conversão para nvarchar(max)ou para um comprimento diferente significa um tipo de dados diferente: o fato de ser tudo nvarcharé irrelevante.

    Além disso, o tipo de dados do lado direito da comparação também é importante. Se for uma variável local ou parâmetro de comprimento diferente, um lado será implicitamente CASTo mais amplo dos 2 tipos de dados (consulte precedência de tipo de dados ).

    Basicamente, se você tiver um general CAST, nvarchar(max)isso estragará as coisas. Eu consideraria corrigir o uso de ntextantes de adicionar CASTtudo.

    A conversão pode não aparecer no plano de consulta. Veja o artigo do blog de Paul White

    • 6
  3. Doran Mackay
    2014-08-02T02:47:41+08:002014-08-02T02:47:41+08:00

    Apenas uma observação, transmitindo assim, onde Datecreated é datetime

     Cast (Datecreated as date) = cast(@MydatetimeValue as date)
    

    Não interrompe a capacidade do SQL de usar índices se existirem índices e, se não existirem, pode resultar no registro de um índice ausente.

    Da mesma forma, ao converter de intpara tinyintou bigintpara intetc, a função de conversão não impede o SQL de usar índices SE o otimizador souber que a operação de conversão não altera a ordem de classificação dos 2 tipos de dados comparáveis.

    Aqui estão vários testes que você pode executar e visualizar o plano real usando o Adventureworks2008R2

    select count(*) from Sales.SalesOrderDetail where SalesOrderID = 8 --1
    select top 10 * from Sales.SalesOrderDetail where cast(SalesOrderID as tinyint) = 8  --2
    select top 10 * from Sales.SalesOrderDetail where cast(SalesOrderID as bigint) = 8  --3
    select top 10 SalesOrderID from Sales.SalesOrderDetail where cast(ModifiedDate  as date) = '19780322' --4
    select top 10 SalesOrderID from Sales.SalesOrderDetail where convert(date,ModifiedDate) = '19780322'  --5
    select top 10 SalesOrderID from Sales.SalesOrderDetail where cast(ModifiedDate as varchar(20)) = '1978'  --6 -- THIS WILL NOT USE INDEX
    select  SalesOrderID from Sales.SalesOrderDetail where cast(ModifiedDate  as date) between '19780101' and '19780109'  --7
    
    • 4

relate perguntas

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como fazer um mysqldump com um banco de dados de uso no dump

    • 4 respostas
  • Marko Smith

    No MySQL Workbench, insira uma nova coluna no "topo" de uma tabela?

    • 4 respostas
  • Marko Smith

    SQL Server - Tabelas temporárias x físicas

    • 3 respostas
  • Marko Smith

    Quando uma varredura de tabela completa é melhor que uma varredura de índice?

    • 4 respostas
  • Marko Smith

    Qual é a diferença entre Shrink Database e File?

    • 3 respostas
  • Marko Smith

    Problema de coleta de lixo Sql FILESTREAM

    • 1 respostas
  • Marko Smith

    Problemas de DBCC do SQL Server 2008

    • 2 respostas
  • Marko Smith

    Como você para, coloca offline e exclui um banco de dados SQL Server em recuperação?

    • 2 respostas
  • Marko Smith

    Como faço para restaurar um banco de dados do SQL Server 2000 para uma instância do SQL Server 2008?

    • 5 respostas
  • Marko Smith

    Desempenho atingido usando CAST em T-SQL

    • 3 respostas
  • Martin Hope
    user481826 Como fazer um mysqldump com um banco de dados de uso no dump 2010-10-29 16:08:59 +0800 CST
  • Martin Hope
    Will A SQL Server - Tabelas temporárias x físicas 2010-07-05 08:46:10 +0800 CST
  • Martin Hope
    NibblyPig Particionamento de tabelas no SQL 2008 - Por quê? 2010-06-30 00:59:23 +0800 CST
  • Martin Hope
    Gnomo Interpretando um plano de execução 2010-09-10 10:31:11 +0800 CST
  • Martin Hope
    ahsan Quando uma varredura de tabela completa é melhor que uma varredura de índice? 2010-12-10 10:16:54 +0800 CST
  • Martin Hope
    Tom DeMille Devo reduzir regularmente meu banco de dados ou pelo menos meu arquivo de log? 2010-04-24 08:19:19 +0800 CST
  • Martin Hope
    Jango Qual é a diferença entre Shrink Database e File? 2010-08-24 10:25:42 +0800 CST
  • Martin Hope
    CrapHands Como você para, coloca offline e exclui um banco de dados SQL Server em recuperação? 2010-12-18 07:12:36 +0800 CST
  • Martin Hope
    Ryan Delucchi Desempenho atingido usando CAST em T-SQL 2010-07-02 15:11:16 +0800 CST
  • Martin Hope
    Manjot SQL 2005: Podemos determinar quanto o trabalho de manutenção do índice de reconstrução pode aumentar os arquivos de log do banco de dados? 2010-08-12 18:40:44 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve