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 / 190132
Accepted
ldrg
ldrg
Asked: 2017-11-05 19:18:50 +0800 CST2017-11-05 19:18:50 +0800 CST 2017-11-05 19:18:50 +0800 CST

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

  • 772

Eu tenho um monte de tabelas que se parecem vagamente com isso:

CREATE TABLE table1(id INTEGER PRIMARY KEY, t1c1 INTEGER, t1c2 INTEGER);
CREATE TABLE table2(id INTEGER PRIMARY KEY, t1 INTEGER REFERENCES table1(id), t2c1 INTEGER);

E eu faço muitas junções onde estou tentando filtrar na tabela unida para obter coisas da primeira tabela, assim:

SELECT t1c1
FROM table1
JOIN table2 ON table2.t1 = table1.id
WHERE t2c1 = 42;

Quando vou escrever índices para uma tabela, olho para as colunas que são usadas na cláusula WHERE e construo índices para satisfazê-las. Então, para esta consulta, eu acabaria escrevendo um índice como este:

CREATE INDEX ON table2 (t2c1);

E esse índice é pelo menos elegível para uso nessa consulta.

Minha pergunta é que, se eu escrever um índice assim:

CREATE INDEX ON table2 (t2c1, t1);

O índice será usado como um índice de cobertura para ajudar o JOIN na consulta acima? Devo alterar minha estratégia de escrita de índice para cobrir colunas de chave estrangeira?

postgresql index
  • 2 2 respostas
  • 30015 Views

2 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2017-11-06T06:24:43+08:002017-11-06T06:24:43+08:00

    O índice será usado como um índice de cobertura para ajudar o JOIN na consulta acima?

    Depende. O Postgres tem varreduras "somente índice" como método de acesso ao índice , não há "índices de cobertura" per se - até o Postgres 10.

    Começando com o Postgres 11 índices de cobertura verdadeiros com INCLUDEcolunas estão disponíveis. Entrada de blog de Michael Paquier apresentando o recurso:

    • https://paquier.xyz/postgresql-2/postgres-11-covering-indexes/

    Resposta relacionada com exemplo de código:

    • Uma consulta com chave primária e chaves estrangeiras é executada mais rapidamente do que uma consulta com apenas chaves primárias?

    Dito isso, o índice CREATE INDEX ON table2 (t2c1, t1);faz todo o sentido para a consulta que você demonstra. Ele pode ser usado para uma varredura somente de índice se pré-condições adicionais forem atendidas, ou pode ser usado em uma varredura de índice de bitmap ou em uma varredura de índice simples. Relacionado:

    • Uso de índice em uma tabela temporária
    • Um índice composto também é bom para consultas no primeiro campo?

    JOINcondições e WHEREcondições são quase completamente equivalentes no Postgres. Eles certamente podem usar índices da mesma maneira. Você pode reescrever sua consulta:

    SELECT t1.t1c1
    FROM   table1 t1
    JOIN   table2 t2 ON t2.t1 = t1.id
    WHERE  t2.t2c1 = 42;
    

    Com este equivalente:

    SELECT t1.t1c1
    FROM   table1 t1 CROSS JOIN table2 t2
    WHERE  t2.t1 = t1.id
    AND    t2.t2c1 = 42;
    

    A primeira forma é obviamente preferível, no entanto. Mais fácil de ler.

    Por que "quase" equivalente? (Não faz diferença para a consulta simples em mãos.)

    • Por que essa junção implícita é planejada de forma diferente de uma junção explícita?

    Relacionado:

    • As junções implícitas são tão eficientes quanto as junções explícitas no Postgres?
    • O que significa [FROM x, y] no Postgres?
    • 22
  2. Evan Carroll
    2017-11-06T13:43:57+08:002017-11-06T13:43:57+08:00

    O índice será usado como um índice de cobertura para ajudar o JOIN na consulta acima? Devo alterar minha estratégia de escrita de índice para cobrir colunas de chave estrangeira?

    Não é provável na consulta acima. Este é um problema complexo enganador com os resultados baseados nas estimativas e seletividade das duas condições,

    • tabela2.t1 = tabela1.id
    • t2c1 = 42

    Essencialmente, você deseja lançar ambos os ambientes (contagens de linhas) para que ambas as condições tenham mais ou menos seletividade. E se você obtiver um loop aninhado, desejará aumentar a quantidade bruta até que esse não seja mais o método de junção mais viável.

    CREATE TABLE table1(
       id INTEGER PRIMARY KEY,
       t1c1 INTEGER,
       t1c2 INTEGER
    );
    INSERT INTO table1(id, t1c1, t1c2)
      SELECT x,x,x FROM generate_series(1,1000)
      AS gs(x);
    
    CREATE TABLE table2(
      id INTEGER PRIMARY KEY,
      t1 INTEGER REFERENCES table1(id),
      t2c1 INTEGER
    );
    INSERT INTO table2(id, t1, t2c1)
    SELECT x,1+x%1000,x%50 FROM generate_series(1,1e6)
      AS gs(x);
    
    EXPLAIN ANALYZE
      SELECT t1c1
      FROM table1
      JOIN table2 ON table2.t1 = table1.id
      WHERE t2c1 = 42;
    

    Agora verifique o plano.

    Agora crie o índice composto,

    CREATE INDEX ON table2 (t2c1, t1);
    VACUUM FULL ANALYZE table1;
    VACUUM FULL ANALYZE table2;
    

    E verifique o plano novamente,

    EXPLAIN ANALYZE
      SELECT t1c1
      FROM table1
      JOIN table2 ON table2.t1 = table1.id
      WHERE t2c1 = 42;
    

    Você pode soltar as chaves e tal para descobrir qual forma ele prefere

    CREATE INDEX ON table2 (t1, t2c1);
    

    ou

    CREATE INDEX ON table2 (t2c1, t1);
    

    Em última análise, embora isso seja muito trabalhoso, sugiro começar com

    CREATE INDEX ON table2 (t1);
    CREATE INDEX ON table2 (t2c1);
    

    E otimizar apenas se isso não for suficiente.

    Você também pode desabilitar opções específicas do planejador para ver se outro plano é realmente mais rápido ou mais lento e, em seguida, procurar corrigi-lo, mas isso também pode ser muito trabalhoso.

    • 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