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 / 125308
Accepted
swasheck
swasheck
Asked: 2016-01-06 13:02:58 +0800 CST2016-01-06 13:02:58 +0800 CST 2016-01-06 13:02:58 +0800 CST

É possível forçar o otimizador a eliminar tabelas irrelevantes nesta visão particionada?

  • 772

Estou testando diferentes arquiteturas para tabelas grandes e uma sugestão que vi é usar uma exibição particionada, em que uma tabela grande é dividida em uma série de tabelas "particionadas" menores.

1 , 2 , 3 , 4

Ao testar essa abordagem, descobri algo que não faz muito sentido para mim. Quando filtro "coluna de particionamento" na visualização de fatos, o otimizador busca apenas nas tabelas relevantes. Além disso, se eu filtrar essa coluna na tabela de dimensões, o otimizador eliminará tabelas desnecessárias.

No entanto, se eu filtrar algum outro aspecto da dimensão, o otimizador busca no PK/CI de cada tabela base.

Aqui estão as perguntas em questão:

select 
    od.[Year], 
    AvgValue = avg(ObservationValue)
from dbo.v_Observation o 
join dbo.ObservationDates od
    on o.ObservationDateKey = od.DateKey
where o.ObservationDateKey >= 20000101
    and o.ObservationDateKey <= 20051231
group by od.[Year];

select 
    od.[Year], 
    AvgValue = avg(ObservationValue)
from dbo.v_Observation o 
join dbo.ObservationDates od
    on o.ObservationDateKey = od.DateKey
where od.DateKey >= 20000101
    and od.DateKey <= 20051231
group by od.[Year];

select 
    od.[Year], 
    AvgValue = avg(ObservationValue)
from dbo.v_Observation o 
join dbo.ObservationDates od
    on o.ObservationDateKey = od.DateKey
where od.[Year] >= 2000 and od.[Year] < 2006
group by od.[Year];

filtro de fato na chave

filtro escuro na tecla

filtro escuro no aspecto

Aqui está um link para a sessão do SQL Sentry Plan Explorer.

Na verdade, estou trabalhando no particionamento da tabela maior para ver se a eliminação da partição responde de maneira semelhante.

Eu obtenho a eliminação da partição para a consulta (simples) que filtra um aspecto da dimensão.

Enquanto isso, aqui está uma cópia somente de estatísticas do banco de dados:

https://gist.github.com/swasheck/9a22bf8a580995d3b2aa

O estimador de cardinalidade "antigo" obtém um plano mais barato, mas isso ocorre devido às estimativas de cardinalidade mais baixas em cada uma das buscas de índice (desnecessárias).

Gostaria de saber se existe uma maneira de fazer com que o otimizador use a coluna chave ao filtrar por outro aspecto da dimensão para que ele possa eliminar buscas em tabelas irrelevantes.

Versão do SQL Server:

Microsoft SQL Server 2014 - 12.0.2000.8 (X64) 
    Feb 20 2014 20:04:26 
    Copyright (c) Microsoft Corporation
    Developer Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
sql-server sql-server-2014
  • 2 2 respostas
  • 877 Views

2 respostas

  • Voted
  1. Best Answer
    Paul White
    2016-01-07T00:34:46+08:002016-01-07T00:34:46+08:00

    Habilite o sinalizador de rastreamento 4199.

    Eu também tive que emitir:

    UPDATE STATISTICS dbo.ObservationDates 
    WITH ROWCOUNT = 73049;
    

    para obter os planos mostrados abaixo. As estatísticas desta tabela estavam ausentes no upload. O valor de 73.049 veio das informações de cardinalidade da tabela no anexo do Plan Explorer. Usei o SQL Server 2014 SP1 CU4 (compilação 12.0.4436) com dois processadores lógicos, memória máxima definida como 2.048 MB e nenhum sinalizador de rastreamento além de 4.199.

    Você deve então obter um plano de execução que apresenta eliminação de partição dinâmica:

    select 
        od.[Year], 
        AvgValue = avg(ObservationValue)
    from dbo.v_Observation o 
    join dbo.ObservationDates od
        on o.ObservationDateKey = od.DateKey
    where 
        od.[Year] >= 2000 and od.[Year] < 2006
    group by 
        od.[Year]
    option (querytraceon 4199);
    

    Fragmento do plano:

    Fragmento de plano

    Isso pode parecer pior, mas os filtros são todos filtros de inicialização . Um exemplo de predicado é:

    Propriedades do filtro

    Por iteração do loop, o predicado de inicialização é testado e somente se ele retornar verdadeiro é que a busca de índice clusterizado abaixo dele é executada. Portanto, eliminação de partição dinâmica.

    Isso talvez não seja tão eficiente quanto a eliminação estática, especialmente se o plano for paralelo.

    Pode ser necessário tentar dicas como MAXDOP 1, FAST 1ou FORCESEEKna exibição para obter o mesmo plano. As opções de custo do otimizador com exibições particionadas (como tabelas particionadas) podem ser complicadas.

    O ponto é que você precisa de um plano que apresente filtros de inicialização para obter a eliminação dinâmica de partições com exibições particionadas.


    Consultas com USE PLANdicas incorporadas: (via gist.github.com):

    • plano de série
    • plano paralelo
    • 10
  2. Geoff Patterson
    2016-01-06T14:01:38+08:002016-01-06T14:01:38+08:00

    Minha observação sempre foi que você deve especificar o valor (ou intervalo de valores) para a coluna de partição explicitamente na consulta para obter "eliminação de tabela" em uma exibição particionada. Isso se baseia na experiência de usar exibições particionadas na produção do SQL Server 2000 até o SQL Server 2014.

    O SQL Server não tem um conceito de operador de junção de loop no qual o mecanismo pode direcionar dinamicamente a busca diretamente para a tabela adequada no lado interno do loop com base no valor da linha no lado externo do loop. No entanto, como explica a resposta de Paul , existe a possibilidade de um plano com filtros de inicialização para pular dinamicamente tabelas irrelevantes no lado interno do loop em tempo constante (em oposição ao logarítmico ao realizar a busca).

    Observe que para tabelas particionadas, no entanto, esse tipo de busca (para uma partição específica) é suportado.

    Se você está determinado a usar exibições particionadas, outra opção é dividir sua consulta em várias consultas, como:

    -- Gather than the min/max values for the partition column
    DECLARE @minDateKey INT,
            @maxDateKey INT
    SELECT @minDateKey = MIN(DateKey),
            @maxDateKey = MAX(DateKey)
    FROM dbo.ObservationDates od
    WHERE od.[Year] >= 2000 and od.[Year] < 2006
    
    -- Since I have a stats-only copy of the database, simulate having run the query above
    -- (You can comment this out since you have the actual data.)
    SELECT @minDateKey = 20000101, @maxDateKey = 20051231
    
    -- Adjust the query to use the min/max values of the partition column
    -- rather than filtering on a different column in the dimension table
    select 
        od.[Year], 
        AvgValue = avg(ObservationValue)
    from dbo.v_Observation o 
    join dbo.ObservationDates od
        on o.ObservationDateKey = od.DateKey
    WHERE od.DateKey >= @minDateKey AND od.DateKey <= @maxDateKey
    group by od.[Year]
    -- Must use OPTION RECOMPILE; otherwise the plan will touch all tables because it
    -- must do so in order to be valid for all values of the parameters!
    OPTION (RECOMPILE)
    

    Isso produz o seguinte plano. Agora há uma consulta extra que atinge a tabela de dimensão, mas a consulta sobre a tabela de fatos (presumivelmente muito maior) é otimizada.

    insira a descrição da imagem aqui

    • 6

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