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 / 108868
Accepted
sharptooth
sharptooth
Asked: 2015-08-04 07:15:51 +0800 CST2015-08-04 07:15:51 +0800 CST 2015-08-04 07:15:51 +0800 CST

Por que DistinctSort é seguido por TopNSort em meu plano de consulta?

  • 772

Eu tenho a seguinte definição:

CREATE TABLE [dbo].[JobItems] (
    [ItemId]            UNIQUEIDENTIFIER NOT NULL,
    [ItemState]         INT              NOT NULL,
    [ItemCreationTime]  DATETIME         NULL DEFAULT GETUTCDATE(),
    [ItemPriority]      TINYINT          NOT NULL DEFAULT(0),
    [ItemRefreshTime]   DATETIME         NULL,
    -- lots of other columns
    CONSTRAINT [PrimaryKey_GUID_HERE] PRIMARY KEY NONCLUSTERED ([ItemId] ASC)
);

CREATE UNIQUE CLUSTERED INDEX [JobItemsIndex]
    ON [dbo].[JobItems]([ItemId] ASC);

CREATE INDEX [GetTaskToProcessIndex]
    ON [dbo].[JobItems]([ItemState], [ItemPriority], [ItemCreationTime])

e a seguinte consulta:

SELECT TOP(1) ItemId FROM JobItems
WHERE ItemState = 5 OR
   ( ( ItemState = 11 ) AND ( DATEDIFF( SECOND, ItemRefreshTime, GETUTCDATE() ) > 14 ) )
ORDER BY ItemPriority ASC, ItemCreationTime ASC

Eu executo esta consulta e inspeciono o plano de execução real e aqui está o que está acontecendo:

  1. A busca de índice é feita para recuperar itens com ItemState=5.
  2. A busca de índice é feita para recuperar itens com ItemState=11e, em seguida, para cada linha, uma busca separada é feita para recuperar ItemRefreshTimee os resultados de duas buscas são filtrados usando loops aninhados.
  3. Conjuntos de 1 e 2 contendo ItemId, ItemCreationTimee ItemPrioritysão concatenados e então...
  4. Mágico DistinctSortacontece com ORDER BY ItemId ASCe finalmente
  5. TopNSortacontece comORDER BY ItemPriority ASC, ItemCreationTime ASC

TopNSorte DistinctSortpegar algo como 32 por cento cada, então ficaria feliz em me livrar DistinctSort- nem mesmo entendo seu propósito.

O que é este mágico TopNSortque é útil DistinctSorte por que ele está lá?

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

1 respostas

  • Voted
  1. Best Answer
    Martin Smith
    2015-08-04T09:58:13+08:002015-08-04T09:58:13+08:00

    Posso reproduzir o plano que você descreve no SQL Server 2012 (no local) executando o DDL em sua pergunta e, em seguida, mexendo nas estatísticas para que o SQL Server pense que a tabela é muito maior que a realidade.

    UPDATE STATISTICS [dbo].[JobItems] WITH ROWCOUNT = 10000000, pagecount = 10000000
    

    E, em seguida, executando a consulta com OPTION (MAXDOP 1, CONCAT UNION, ORDER GROUP).

    insira a descrição da imagem aqui

    Este é um plano de união de índice . O operador de concatenação implementa UNION ALL. O Distinct Sort altera a semântica para uma UNIONoperação para evitar que a mesma linha seja retornada várias vezes. (No caso de a tabela não ter uma chave de índice para atuar como um identificador de linha exclusivo, o rid físico teria sido usado aqui para evitar a duplicação incorreta de diferentes linhas que possuem os mesmos valores de coluna)

    Um exemplo de onde isso pode ser necessário está na consulta abaixo. (observe que os dois parâmetros são definidos com o mesmo valor, portanto, um plano de união de índice buscaria as mesmas linhas duas vezes)

    DECLARE @ItemState1   INT = 5
            , @ItemState2 INT = 5
    
    SELECT ItemId
    FROM   JobItems
    WHERE  ItemState = @ItemState1
            OR ( ( ItemState = @ItemState2 )
                 AND ( DATEDIFF(SECOND, ItemRefreshTime, GETUTCDATE()) > 14 ) )
    

    O Top N Sort então reclassifica os dados para implementar o TOP 1.

    No seu caso, o Distinct Sort não é logicamente necessário por vários motivos. As ramificações ItemState = 5e ItemState = 11são mutuamente exclusivas (e isso pode ser determinado em tempo de compilação) e, além disso, a TOP 1 ... ORDER BY ItemPriority ASC, ItemCreationTime ASCsemântica não seria afetada mesmo se houvesse duplicatas incorretas.

    Uma maneira alternativa de escrever a consulta (que fornece um plano melhor usando os índices para evitar qualquer classificação) é

    SELECT TOP(1) ItemId
    FROM   (SELECT ItemId,
                   ItemPriority,
                   ItemCreationTime
            FROM   JobItems
            WHERE  ItemState = 5
            UNION ALL
            SELECT ItemId,
                   ItemPriority,
                   ItemCreationTime
            FROM   JobItems
            WHERE  ( ( ItemState = 11 )
                     AND ( DATEDIFF(SECOND, ItemRefreshTime, GETUTCDATE()) > 14 ) )) T
    ORDER  BY ItemPriority ASC,
              ItemCreationTime ASC 
    

    insira a descrição da imagem aqui

    Você pode considerar adicionar ItemRefreshTimeuma coluna incluída ao índice para evitar a pesquisa de chave se, na prática, algumas forem necessárias antes de localizar uma única linha que satisfaça o predicado residual.

    • 7

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