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 / 155881
Accepted
BanksySan
BanksySan
Asked: 2016-11-22 05:41:06 +0800 CST2016-11-22 05:41:06 +0800 CST 2016-11-22 05:41:06 +0800 CST

Desempenho de indexação inesperado (tudo é igual)

  • 772

Eu queria ver os efeitos de ter índices em colunas calculadas, então criei uma tabela como esta:

CREATE TABLE [Domain\UserName].[CompColIndexing](
    [a] [int] NOT NULL,
    [nonIndexedNonPersisted]  AS ([a]+(1)),
    [nonIndexedPersisted]  AS ([a]+(1)) PERSISTED,
    [IndexedNonPersisted]  AS ([a]+(1)),
    [IndexedPersisted]  AS ([a]+(1)) PERSISTED
) ON [DATA]

Adicionei 800,000linhas a isso, com o valor para apercorrer 0até 9.

Os seguintes índices foram adicionados:

CREATE NONCLUSTERED INDEX [IX_DJB_CompNonPersisted] ON [Domain\UserName].[CompColIndexing] 
(
    [IndexedNonPersisted] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [DATA]
GO

CREATE NONCLUSTERED INDEX [IX_DJB_CompPersisted] ON [Domain\UserName].[CompColIndexing] 
(
    [IndexedPersisted] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [DATA]
GO

Então eu executei algumas ORDER BYcláusulas para ver quais diferenças de desempenho eu obteria, planejando depois para ver como a mudança de valores aafetaria as coisas.

SELECT *
FROM [EMEA\BanksD].[CompColIndexing]
ORDER BY a

SELECT *
FROM [EMEA\BanksD].[CompColIndexing]
ORDER BY nonIndexedNonPersisted

SELECT *
FROM [EMEA\BanksD].[CompColIndexing]
ORDER BY IndexedNonPersisted

SELECT *
FROM [EMEA\BanksD].[CompColIndexing]
ORDER BY nonIndexedPersisted

SELECT *
FROM [EMEA\BanksD].[CompColIndexing]
ORDER BY IndexedPersisted

Porém, inesperadamente, descobri que obtenho exatamente o mesmo resultado para cada uma das consultas:

Saída do Profiler

Eu esperava pelo menos que a SORToperação na primeira consulta fosse mais lenta, pois essa não é indexada.

O que está acontecendo aqui?

A cardinalidade é baixa propositalmente, na verdade, preciso classificar em três valores diferentes.

estou a usarMicrosoft SQL Server 2008 R2 (SP2) - 10.50.4042.0 (X64)

Planos de execução reais disponíveis em: https://www.brentozar.com/pastetheplan/?id=S10MTuxGg

sql-server sql-server-2008-r2
  • 1 1 respostas
  • 92 Views

1 respostas

  • Voted
  1. Best Answer
    Joe Obbish
    2016-11-22T07:13:19+08:002016-11-22T07:13:19+08:00

    A definição da tabela que você tem está levando a um comportamento realmente estranho do otimizador. Suspeito que você esteja enfrentando o problema documentado nesta postagem do SE . Para evitar esse problema, vou criar a tabela apenas com as colunas [a] e [IndexedPersisted].

    As dicas de consulta podem ser úteis para descobrir por que o otimizador não escolheu o plano que você esperava. Aqui você esperava que o índice fosse usado, mas o SQL Server não o usou. Vamos ver ambos os planos de consulta lado a lado:

    SELECT *
    FROM [dbo].[CompColIndexing]
    ORDER BY [IndexedPersisted]
    OPTION (MAXDOP 1);
    
    SELECT *
    FROM [dbo].[CompColIndexing] WITH (INDEX([IX_DJB_CompPersisted]))
    ORDER BY [IndexedPersisted]
    OPTION (MAXDOP 1);
    

    planos de consulta

    O otimizador de consulta considera que a classificação após a varredura da tabela é mais barata do que 800.000 pesquisas RID. Talvez esteja errado, então vamos executar as consultas e comparar as métricas de desempenho para elas.

    cpu_time    total_elapsed_time  logical_reads   reads
    1204        1395                3087            1485
    1516        1570                851798          0
    

    Eu obtive esses números olhando para sys.dm_exec_sessions depois de executar as consultas em sessões separadas com "descartar resultados após a execução" marcada para que eu não precisasse esperar que as linhas fossem retornadas ao cliente.

    Esses números me parecem razoáveis. Só porque um índice pode ser usado não significa que ele deva ser usado, especialmente se o SQL Server precisar ler a tabela inteira usando o índice. Esse é o pior caso de uso para um índice que posso imaginar. Os índices podem ser muito úteis ao selecionar uma pequena porcentagem de linhas da tabela ou quando estão cobrindo índices.

    O índice é abrangente se eu selecionar apenas a coluna [IndexedPersisted]. Nesse caso, o servidor SQL acha que usar o índice é mais barato do que fazer uma varredura na tabela. Código para comparar os dois métodos:

    -- force table scan
    SELECT [IndexedPersisted]
    FROM [dbo].[CompColIndexing] WITH (INDEX(0))
    ORDER BY [IndexedPersisted]
    OPTION (MAXDOP 1);
    
    SELECT [IndexedPersisted]
    FROM [dbo].[CompColIndexing] WITH (INDEX([IX_DJB_CompPersisted]))
    ORDER BY [IndexedPersisted]
    OPTION (MAXDOP 1);
    

    plano de consulta 2

    Aqui estão os números de desempenho:

    cpu_time    total_elapsed_time  logical_reads   reads
    1171        1212                2727            1088
    343         406                 1798            0
    

    Agora que o índice é um índice de cobertura, é um caminho de acesso melhor para a tabela do que uma varredura de tabela.

    • 4

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