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 / 51998
Accepted
u23432534
u23432534
Asked: 2013-10-23 10:50:07 +0800 CST2013-10-23 10:50:07 +0800 CST 2013-10-23 10:50:07 +0800 CST

Forçar spool para evitar a criação de tabelas temporárias?

  • 772

Eu tenho a seguinte consulta que une dados dinâmicos de várias tabelas muito grandes e é executado muito lentamente. Tentei criar a tabela temporária para cada giro e ela roda muito mais rápido. É uma maneira de forçar o spool de índice/tabela sem criar tabelas temporárias?

select ...
from T1 ....
left join (select ... from (select ... from T2....) pivot (sum(C1) on C2 in (...))) p1 
    on ...
left join (select ... from (select ... from T3....) pivot (sum(...) on ... in (...))) p2
    on ...
left join (select ... from (select ... from T4....) pivot (sum(...) on ... in (...))) p3
    on ...
sql-server sql-server-2008
  • 3 3 respostas
  • 1519 Views

3 respostas

  • Voted
  1. erdomke
    2014-09-30T07:32:28+08:002014-09-30T07:32:28+08:00

    Uma pergunta muito semelhante foi feita e respondida no StackOverflow: Como posso forçar uma subconsulta a funcionar tão bem quanto uma tabela #temp? Para resumir,

    1. O método mais confiável é simplesmente usar uma #tempmesa e materializá-la você mesmo.
    2. Caso contrário, consulte Fornecer uma dica para forçar a materialização intermediária de CTEs ou tabelas derivadas . O uso de TOP(large_number) ... ORDER BYmuitas vezes pode encorajar o resultado a ser colocado em spool em vez de repetidamente reavaliado. Mesmo que funcione, no entanto, não há estatísticas no carretel.
    3. Outra opção é usar uma função definida pelo usuário. As funções de várias instruções (conforme descritas em Como compartilhar dados entre procedimentos armazenados ) parecem forçar o SQL Server a materializar os resultados de sua subconsulta. Além disso, eles permitem que você especifique chaves primárias e índices na tabela resultante para ajudar o otimizador de consulta. Essa função pode então ser usada em uma instrução select como parte de sua visualização. Por exemplo:
    CREATE FUNCTION SalesByStore (@storeid varchar(30))
       RETURNS @t TABLE (title varchar(80) NOT NULL PRIMARY KEY,
                         qty   smallint    NOT NULL)  AS
    BEGIN
       INSERT @t (title, qty)
          SELECT t.title, s.qty
          FROM   sales s
          JOIN   titles t ON t.title_id = s.title_id
          WHERE  s.stor_id = @storeid
       RETURN
    END
    
    CREATE VIEW SalesData As
    SELECT * FROM SalesByStore('6380')
    
    • 4
  2. Best Answer
    Sebastian Meine
    2013-10-23T11:16:48+08:002013-10-23T11:16:48+08:00

    O SQL Server não tem uma dica force_spool.

    Você pode "codificar" manualmente um plano de execução que inclua um spool e, em seguida, forçar seu uso com uma dica de plano. No entanto, ainda não experimentei esse método.


    Editar:

    A codificação manual de um plano de execução está além do escopo deste fórum. Aqui estão algumas dicas para você começar:

    • O plano de execução do SQL Server é representado como XML. Você pode pensar nisso como uma linguagem de programação complexa.
    • A especificação do esquema XML explica a sintaxe desta linguagem: http://schemas.microsoft.com/sqlserver/2004/07/showplan/
    • dentro de cada plano de execução você tem uma hierarquia de nós "RelOp" com um único nó raiz. Este nó raiz é onde a execução começa. O operador relacional (RelOp) é executado e solicita linhas de seu filho (ou filhos). Esses, por sua vez, executam para chamar recursivamente seus filhos.

    A melhor maneira de começar é ler planos de execução XML simples.

    Para colocar um carretel lá, você deve ser capaz de injetar um carretel em qualquer lugar que faça sentido. O plano de execução, no entanto, será verificado pelo SQL Server para ser válido para a consulta em questão e pode ser rejeitado.

    Novamente, esta é apenas uma sugestão de pesquisa e eu ainda não tentei.

    • 2
  3. wBob
    2013-10-25T07:59:12+08:002013-10-25T07:59:12+08:00

    O que há de errado em persistir os resultados intermediários em uma tabela temporária? Muitas vezes, é uma abordagem sólida ao ajustar o desempenho. Pode não fornecer a consulta mais rápida em comparação com uma consulta in-line "perfeita", mas proporcionará resultados mais previsíveis.

    Suspeito que você esteja enfrentando um problema de cardinalidade devido à complexidade da consulta. Você tem grandes discrepâncias entre as contagens de linhas estimadas e reais em seu plano de execução? Você pode postar seu XML do Plano de Execução Real? Enquanto isso, uma das dicas de consulta pode ajudar, por exemplo

    OPTION ( HASH JOIN )
    

    No meu equipamento simples , isso gerou uma consulta mais rápida, mas com uso mais intenso da CPU. Eu realmente não posso recomendar cortar seu próprio plano de execução. Levaria cerca de 30 segundos para refatorar sua consulta para trabalhar com tabelas temporárias, nas quais você poderia passar horas mexendo no xml do plano de execução e ainda assim não obter um resultado.

    • 0

relate perguntas

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

  • Quanto "Padding" coloco em meus índices?

  • Existe um processo do tipo "práticas recomendadas" para os desenvolvedores seguirem para alterações no banco de dados?

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

  • Downgrade do SQL Server 2008 para 2005

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • 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

    Conceder acesso a todas as tabelas para um usuário

    • 5 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
    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
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +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