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 / 331776
Accepted
Morgeth888
Morgeth888
Asked: 2023-10-03 01:16:05 +0800 CST2023-10-03 01:16:05 +0800 CST 2023-10-03 01:16:05 +0800 CST

Por que o SQL Server não pode executar um TOP N SORT entre uma busca de índice e uma pesquisa de chave?

  • 772

Estou analisando um pequeno problema de desempenho, em que uma ferramenta otimizadora está basicamente dizendo: "ei, vá em frente e inclua todas as colunas desta tabela neste índice", o que é uma solução horrível na minha opinião.

Meu processo de pensamento me levou a pensar "por que não vou em frente e dou tudo neste índice existente para fazer sua classificação e operação TOP(N) e cortar essa enorme operação de pesquisa de chave de 100k, certamente o SQL Server pode fazer isso e mude de pesquisas de chave de 100 mil para N."

Não foi isso que eu vi, o que vi foi que nada mudou, ele ainda fazia todas as principais pesquisas e classificava depois disso. Como abaixo

insira a descrição da imagem aqui

Simplesmente remover a seleção das outras colunas que não estão no índice faz com que ele não precise de nenhuma pesquisa de chave, é claro.

Já vi muitas soluções alternativas usando CTE para contornar isso, mas estou usando o Entity Framework para esta consulta e simplesmente brincar com a consulta não é tão fácil assim.

Eu gostaria que o objetivo principal desta pergunta fosse POR QUE isso acontece? Parece uma operação trivial fazer a cláusula sort e top antes do loop de pesquisa de chave, se você puder. Não fazer isso parece uma fraqueza gritante na plataforma.

Estou perguntando por que esse comportamento existe, e não como posso melhorar o desempenho dessa consulta.

sql-server
  • 2 2 respostas
  • 91 Views

2 respostas

  • Voted
  1. Erik Darling
    2023-10-03T03:16:37+08:002023-10-03T03:16:37+08:00

    amor próprio

    Você provavelmente pode obter a forma do plano que deseja fazendo uma auto-junção, o que é muito mais fácil de fazer no Entity Framework do que em todas as coisas do CTE. Também é uma opção mais confiável porque os CTEs podem ser instáveis.

    Se tivermos este índice:

    CREATE INDEX 
        whatever 
    ON dbo.Users 
        (Reputation, Age, CreationDate)
    WITH(SORT_IN_TEMPDB = ON);
    

    E esta consulta:

    SELECT TOP (1000) 
        u2.*
    FROM dbo.Users AS u
    JOIN dbo.Users AS u2
        ON u.Id = u2.Id
    WHERE u.Reputation = 2
    ORDER BY 
        u.CreationDate DESC;
    

    O plano resultante é assim:

    NOZES

    os detalhes

    O que você deseja fazer é que uma instância da auto-junção (neste caso, o ualias) cuide da cláusula where e ordene por, e a outra referência (neste caso u2) cuide da lista de seleção.

    Você pode ver no plano de consulta que a classificação atende à meta de 1.000 linhas antes de entrar na junção.

    No caso de um plano de execução paralelo (como o da sua pergunta), você poderá ver um número um pouco maior entrando na classificação antes de ser descartado pelo TOP.

    NOZES

    Há alguns detalhes adicionais sobre por que isso está aqui:

    • Planos de execução paralela são uma droga
    • 3
  2. Best Answer
    Paul White
    2023-10-03T15:38:09+08:002023-10-03T15:38:09+08:00

    Eu gostaria que o objetivo principal desta pergunta fosse POR QUE isso acontece? Parece uma operação trivial fazer a cláusula sort e top antes do loop de pesquisa de chave, se você puder.

    Existem três razões principais:

    1. Uma pesquisa está fortemente vinculada ao seu operador pai.

      A operação lógica é GETretornar atributos de uma relação. A implementação física dessa operação lógica pode assumir várias formas:

      • Digitalizar uma tabela, índice ou visualização indexada correspondente
      • Procure em um índice, uma ou várias vezes
      • Digitalizar ou procurar(ões) mais pesquisa
      • Predicado residual na varredura, busca ou pesquisa

      Qualquer que seja a opção física escolhida, o SQL Server deve respeitar a intenção e a semântica originais do GET, incluindo o tempo de vida do bloqueio e outras garantias de consistência e invariantes internos.

      Como resultado, há poucos operadores permitidos entre uma varredura ou busca e qualquer pesquisa relacionada. Isso inclui uma classificação nas chaves de cluster introduzidas para otimizar E/S sequencial na pesquisa e um spool pronto para proteção de Halloween .

    2. Um "Top" não é um operador relacional. A maior parte do otimizador é construída sobre princípios relacionais e equivalências. Algum apoio específico foi adicionado (ou omitido deliberadamente) ao Top ao longo do tempo, mas estes ainda são uma minoria.

      Conseqüentemente, o otimizador não considera muito as colocações alternativas dos operadores principais.

    3. Um "Top N Sort" é uma reescrita pós-otimização para potencialmente executar uma classificação de seleção de substituição em vez de usar o algoritmo geral.

      Por ser uma reescrita pós-otimização, ela não está sujeita ao controle de custos e não faz parte do raciocínio do otimizador.

      A reescrita é limitada aos casos em que o operador Top físico termina imediatamente após um operador Sort no plano de execução escolhido pelo otimizador.

      Dado que o otimizador não explora muito a movimentação do Top pela árvore do plano, é fácil acabar com o Top separado do Sort (que pode se movimentar muito mais, mas não tanto quanto os verdadeiros operadores relacionais).

    Não fazer isso parece uma fraqueza gritante na plataforma.

    Bem, é. As pessoas têm escrito sobre maneiras de expressar dúvidas para obter melhores resultados há uma década ou mais. Também não é a única fraqueza.

    Por outro lado, o otimizador do SQL Server tem como objetivo encontrar rapidamente um plano de execução aparentemente razoável. Ele não tem os mesmos objetivos de um compilador otimizador encontrado em linguagens de programação, que têm muito mais liberdade e tempo para encontrar e aplicar seus truques.

    Estou usando o Entity Framework para esta consulta e simplesmente brincar com a consulta não é tão fácil assim.

    Lamento ouvir isso.

    • 3

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