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 / 159333
Accepted
Paul White
Paul White
Asked: 2016-12-29 05:20:49 +0800 CST2016-12-29 05:20:49 +0800 CST 2016-12-29 05:20:49 +0800 CST

O SQL Server armazena em cache o resultado de uma função com valor de tabela de várias instruções?

  • 772

Uma função com valor de tabela com várias instruções retorna seu resultado em uma variável de tabela.

Esses resultados são reutilizados ou a função é sempre totalmente avaliada toda vez que é chamada?

sql-server execution-plan
  • 1 1 respostas
  • 3195 Views

1 respostas

  • Voted
  1. Best Answer
    Paul White
    2016-12-29T05:20:49+08:002016-12-29T05:20:49+08:00

    Os resultados de uma função com valor de tabela de várias instruções (msTVF) nunca são armazenados em cache ou reutilizados em instruções (ou conexões), mas há algumas maneiras pelas quais um resultado msTVF pode ser reutilizado na mesma instrução. Nesse sentido, um msTVF não é necessariamente repovoado toda vez que é chamado.

    Exemplo msTVF

    Este msTVF (deliberadamente ineficiente) retorna um intervalo especificado de inteiros, com um registro de data e hora em cada linha:

    IF OBJECT_ID(N'dbo.IntegerRange', 'TF') IS NOT NULL
        DROP FUNCTION dbo.IntegerRange;
    GO
    CREATE FUNCTION dbo.IntegerRange (@From integer, @To integer)
    RETURNS @T table 
    (
        n integer PRIMARY KEY, 
        ts datetime DEFAULT CURRENT_TIMESTAMP
    )
    WITH SCHEMABINDING
    AS
    BEGIN
        WHILE @From <= @To
        BEGIN
            INSERT @T (n)
            VALUES (@From);
    
            SET @From = @From + 1;
        END;
        RETURN;
    END;
    

    Variável de tabela estática

    Se todos os parâmetros para a chamada de função forem constantes (ou constantes de tempo de execução), o plano de execução preencherá o resultado da variável da tabela uma vez. O restante do plano pode acessar a variável de tabela várias vezes. A natureza estática da variável de tabela pode ser reconhecida no plano de execução. Por exemplo:

    SELECT
        IR.n,
        IR.ts 
    FROM dbo.IntegerRange(1, 5) AS IR
    ORDER BY
        IR.n;
    

    Retorna um resultado semelhante a:

    resultado simples

    O plano de execução é:

    Plano de execução simples

    O operador Sequence primeiro chama o operador Table Valued Function, que preenche a variável da tabela (observe que esse operador não retorna nenhuma linha). Em seguida, a Sequência chama sua segunda entrada, que retorna o conteúdo da variável de tabela (usando um Clustered Index Scan neste caso).

    A indicação de que o plano está usando um resultado de variável de tabela 'estática' é o operador Table Valued Function abaixo de uma sequência - a variável de tabela precisa ser totalmente preenchida uma vez antes que o restante do plano possa prosseguir.

    Múltiplos acessos

    Para mostrar o resultado da variável da tabela acessada mais de uma vez, usaremos uma segunda tabela com linhas numeradas de 1 a 5:

    IF OBJECT_ID(N'dbo.T', 'U') IS NOT NULL
        DROP TABLE dbo.T;
    
    CREATE TABLE dbo.T (i integer NOT NULL);
    
    INSERT dbo.T (i) 
    VALUES (1), (2), (3), (4), (5);
    

    E uma nova consulta que une esta tabela à nossa função (isso também pode ser escrito como um APPLY):

    SELECT T.i,
           IR.n,
           IR.ts
    FROM dbo.T AS T
    JOIN dbo.IntegerRange(1, 5) AS IR
        ON IR.n = T.i;
    

    O resultado é:

    Resultado da junção

    O plano de execução:

    Entrar no plano

    Como antes, a sequência preenche primeiro o resultado da variável de tabela msTVF. Em seguida, os loops aninhados são usados ​​para unir cada linha da tabela Ta uma linha do resultado msTVF. Como a definição da função incluiu um índice útil na variável de tabela, uma busca de índice pode ser usada.

    O ponto chave é que quando os parâmetros para o msTVF são constantes (incluindo variáveis ​​e parâmetros) ou tratados como constantes de tempo de execução para a instrução pelo mecanismo de execução, o plano apresentará dois operadores separados para o resultado da variável da tabela msTVF: um para preencher o tabela; outro para acessar os resultados, possivelmente acessando a tabela várias vezes e possivelmente fazendo uso de índices declarados na definição da função.

    Parâmetros correlacionados e parâmetros não constantes

    Para destacar as diferenças quando parâmetros correlacionados (referências externas) ou parâmetros de funções não constantes são usados, vamos alterar o conteúdo da tabela Tpara que a função tenha muito mais trabalho a fazer:

    TRUNCATE TABLE dbo.T;
    
    INSERT dbo.T (i) 
    VALUES (50001), (50002), (50003), (50004), (50005);
    

    A consulta modificada a seguir agora usa uma referência externa à tabela Tem um dos parâmetros da função:

    SELECT T.i,
           IR.n,
           IR.ts
    FROM dbo.T AS T
    CROSS APPLY dbo.IntegerRange(1, T.i) AS IR
    WHERE IR.n = T.i;
    

    Essa consulta leva cerca de 8 segundos para retornar resultados como:

    resultado correlacionado

    Observe a diferença de tempo entre as linhas na coluna ts. A WHEREcláusula limita o resultado final para uma saída de tamanho razoável, mas a função ineficiente ainda demora um pouco para preencher a variável de tabela com 50.000 linhas ímpares (dependendo do valor correlacionado de ifrom table T).

    O plano de execução é:

    Plano de execução correlacionado

    Observe a falta de um operador Sequence. Agora, há um único operador Table Valued Function que preenche a variável de tabela e retorna suas linhas em cada iteração da união de loops aninhados.

    Para ser claro: com apenas 5 linhas na tabela T, o operador Table Valued Function é executado 5 vezes. Ele gera 50.001 linhas na primeira iteração, 50.002 na segunda... e assim por diante. A variável de tabela é 'jogada fora' (truncada) entre as iterações, então cada uma das cinco chamadas é uma população completa. É por isso que é tão lento e cada linha leva aproximadamente o mesmo tempo para aparecer no resultado.

    Notas laterais:

    Naturalmente, o cenário acima é deliberadamente planejado para mostrar como o desempenho ruim pode ser quando o msTVF preenche muitas linhas em cada iteração.

    Uma implementação sensata do código acima definiria ambos os parâmetros msTVF como , e removeria a cláusula iredundante . WHEREA variável de tabela ainda seria truncada e preenchida novamente em cada iteração, mas apenas com uma linha de cada vez.

    Também poderíamos buscar os ivalores mínimo e máximo Te armazená-los em variáveis ​​em uma etapa anterior. Chamar a função com variáveis ​​em vez de parâmetros correlacionados permitiria que o padrão de variável de tabela 'estática' fosse usado conforme observado anteriormente.

    Cache para parâmetros correlacionados inalterados

    Voltando à questão original mais uma vez, onde o padrão estático Sequence não pode ser usado, o SQL Server pode evitar o truncamento e o repovoamento da variável de tabela msTVF se nenhum dos parâmetros correlacionados tiver sido alterado desde a iteração anterior de uma junção de loop aninhada.

    Para demonstrar isso, substituiremos o conteúdo de Tpor cinco valores idênticos i :

    TRUNCATE TABLE dbo.T;
    
    INSERT dbo.T (i) 
    VALUES (50005), (50005), (50005), (50005), (50005);
    

    A consulta com um parâmetro correlacionado novamente:

    SELECT T.i,
           IR.n,
           IR.ts
    FROM dbo.T AS T
    CROSS APPLY dbo.IntegerRange(1, T.i) AS IR
    WHERE IR.n = T.i;
    

    Desta vez, os resultados aparecem em cerca de 1,5 segundos :

    Resultados de linha idênticos

    Observe os timestamps idênticos em cada linha. O resultado armazenado em cache na variável de tabela é reutilizado para iterações subsequentes em que o valor correlacionado ipermanece inalterado. Reutilizar o resultado é muito mais rápido do que inserir 50.005 linhas de cada vez.

    O plano de execução é muito semelhante ao anterior:

    Planejar linhas idênticas

    A principal diferença está nas propriedades Actual Rebinds e Actual Rewinds do operador Table Valued Function:

    Propriedades do operador

    Quando os parâmetros correlacionados não mudam, o SQL Server pode reproduzir (rebobinar) os resultados atuais na variável de tabela. Quando a correlação muda, o SQL Server deve truncar e preencher novamente a variável de tabela (revincular). A única religação acontece na primeira iteração; as quatro iterações subsequentes são todas retrocessos, pois o valor de T.ipermanece inalterado.

    • 26

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

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

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

Sidebar

Stats

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

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +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