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 / 294898
Accepted
Sahap Asci
Sahap Asci
Asked: 2021-06-28 08:49:15 +0800 CST2021-06-28 08:49:15 +0800 CST 2021-06-28 08:49:15 +0800 CST

Melhor ordem de classificação no índice da árvore B para dar suporte à consulta em linhas recentes?

  • 772

Suponha que eu tenha uma tabela que tenha uma descrição como:

create table my_table (
  id serial, 
  create_date timestamp with time zone default now(),
  data text
);

e uma consulta como:

select * from my_table
where create_date >= timestamp with time zone 'yesterday'

Qual índice será teoricamente mais rápido e por quê?

create index index_a on my_table (create_date);

create index index_b on my_table (create_date DESC);
postgresql index
  • 1 1 respostas
  • 784 Views

1 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2021-06-28T16:40:49+08:002021-06-28T16:40:49+08:00

    Não gosto do nome "create_date" para uma coluna que não é realmente uma, datemas uma timestamptz. Usando "created_at" em vez disso.

    Como created_atpode ser NULL, esta 3ª variante será mais rápida (mesmo que não muito):

    CREATE INDEX index_c ON my_table (created_at DESC NULLS LAST);
    

    NULLvalores são classificados após o maior valor por padrão. DESCENDINGA ordem de classificação é a inversão perfeita, portanto, os NULLvalores vêm primeiro. Ver:

    • Classificar por coluna ASC, mas valores NULL primeiro?

    O Postgres pode escanear índices de árvore B para trás quase na mesma velocidade, então ambas as suas variantes estão quase no mesmo nível. Mas o operador >=exclui NULLvalores (como a maioria dos operadores). Portanto, o Postgres precisa pular os NULLvalores iniciais / finais, respectivamente, primeiro. Normalmente não é caro, mas ainda assim.

    O índice com DESC NULLS LAST(ou NULLS FIRST) tem os maiores valores primeiro e os NULLvalores por último (ou vice-versa), então a consulta pode começar a ler diretamente do topo (abaixo) do índice.

    Se não pode haver NULLvalores, não haverá diferença perceptível. E você deve declarar a coluna NOT NULL. (E você deveria ter dito isso.)

    Se as inserções vierem com timestamps estritamente ascendentes (e não houver atualizações!) - ou se isso for verdade para linhas inseridas recentemente desde "ontem", as linhas (relevantes) são fisicamente agrupadas por timestamp automaticamente. Caso contrário, pode valer a pena agrupar fisicamente as linhas de tempos em tempos. (Sem interferir no carregamento simultâneo no banco de dados!) Isso pode fazer uma diferença maior, pois mantém o número de páginas de dados que precisam ser lidas no mínimo. Ver:

    • Configurando o PostgreSQL para desempenho de leitura

    Se sua mesa for grande, um índice parcial pode pagar:

    CREATE INDEX index_c_partial ON my_table (created_at DESC NULLS LAST)
    WHERE  created_at >= '2021-06-26 0:0';  -- recent but before yesterday
    

    Ele corta a maioria das linhas antigas, para que o índice diminua para uma fração de tamanho.

    Mas como seu cut-off ( 'yesterday') é um alvo móvel, você terá que recriar esse índice de tempos em tempos para remover tuplas antigas, ou o benefício se deteriorará com o tempo. Tipo, diariamente, semanalmente, mensalmente - você decide.

    Com o cache quente, esse índice parcial não será muito mais rápido que o índice completo, mas como é muito menor, suas chances de permanecer no cache são maiores (depende da sua configuração completa), o que normalmente faz uma grande diferença. (E não ocupa tantos recursos para começar.)

    Como temos um índice tão pequeno agora, e enquanto lidamos com poucas colunas (ou você não precisa realmente SELECT *começar?!), podemos também torná-lo um índice de cobertura (Postgres 11 ou posterior):

    CREATE INDEX index_c_partial_covering ON my_table
       (created_at DESC NULLS LAST) INCLUDE (id, data)
    WHERE  created_at >= '2021-06-26 0:0';
    

    Novamente, os detalhes dependem da situação completa. Relacionado:

    • A cobertura de índices no PostgreSQL ajuda as colunas JOIN?

    Se algumas pré-condições forem atendidas, você obterá varreduras somente de índice mais baratas agora. A ordem física das linhas na tabela não importa neste caso.


    Ah, e mova essa timestamptzcoluna para uma posição diferente na definição da tabela. A maneira como você o tem agora maximiza o inchaço devido ao preenchimento de alinhamento. Qualquer outra posição para a timestamptzcoluna é melhor. Curti:

    CREATE TABLE my_table (
    , created_at timestamptz DEFAULT now() NOT NULL
    , id serial NOT NULL PRIMARY KEY
    , data text
    );
    

    Ver:

    • Calculando e economizando espaço no PostgreSQL
    • 4

relate perguntas

  • Quanto "Padding" coloco em meus índices?

  • Sequências Biológicas do UniProt no PostgreSQL

  • O que significa "índice" em RDBMSs? [fechado]

  • Como criar um índice condicional no MySQL?

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

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