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 / 161812
Accepted
jpmc26
jpmc26
Asked: 2017-01-21 13:03:35 +0800 CST2017-01-21 13:03:35 +0800 CST 2017-01-21 13:03:35 +0800 CST

A inserção em ordem tem o mesmo efeito que o agrupamento?

  • 772

Eu tenho uma tabela que conterá alguns dados pré-calculados com base em outras tabelas. (Computar em tempo real é muito caro computacionalmente, dado o tamanho dos dados com os quais tenho que lidar.) Estarei gerando de forma incremental à medida que os dados de origem forem adicionados. (Nunca precisarei UPDATEdisso em uso normal; partes podem ser excluídas e regeneradas.) A tabela será bastante grande. Atualmente, são cerca de 50 milhões de linhas e crescerão a cada ano.

A maioria das consultas nesta tabela será filtrada por uma coluna de ID de chave estrangeira. Dessa forma, eles têm um desempenho melhor se todas as linhas desse ID forem agrupadas nas mesmas páginas. Posso garantir essa ordenação no disco criando um índice e chamando CLUSTERperiodicamente, mas isso obviamente não é o ideal, pois exigiria algum tipo de tarefa agendada, coordenando com o uso e outras tarefas agendadas, etc.

No entanto, como estou gerando esses dados em pedaços relacionados à chave estrangeira que quero CLUSTER, posso facilmente colocar uma ORDER BYcláusula no INSERTcomando:

INSERT INTO big_table (source_table1_id,a,b,c)
SELECT
   source_table1_id,
   5 /* some formula */,
   /* ... */
FROM source_table1
JOIN source_table2 ON ...
...
WHERE ... /* some condition indicating what needs to be generated */
ORDER BY source_table1_id

Isso afetará a ordem de armazenamento em disco, agrupando as linhas em um número próximo ao mínimo de páginas? E se isso acontecer, existem outros processos que podem atrapalhar a ordem do disco mais tarde?

Atualmente estou usando o PostgreSQL 9.3, mas gostaria de saber sobre as versões mais recentes também para atualizações.

postgresql performance
  • 4 4 respostas
  • 1221 Views

4 respostas

  • Voted
  1. mustaccio
    2017-01-21T13:32:11+08:002017-01-21T13:32:11+08:00

    As linhas serão processadas na ordem garantida, mas isso não significa que após serem inseridas elas ficarão localizadas uma ao lado da outra. Isso só será possível se os registros nunca forem excluídos ou atualizados em sua tabela. Depois de atualizar ou excluir algumas linhas, após a limpeza, você provavelmente terá espaço livre no meio da tabela, para onde irão os próximos registros inseridos.

    Alguns detalhes extras nesta questão .

    • 3
  2. Best Answer
    Erwin Brandstetter
    2017-01-23T19:19:19+08:002017-01-23T19:19:19+08:00

    O Postgres escreve fisicamente as tuplas sequencialmente como INSERTed. Se você fizer isso em uma nova tabela ou em uma tabela sem tuplas mortas, obterá exatamente o mesmo resultado que obteria CLUSTERem um índice com a mesma ordem de classificação que seu arquivo INSERT. O efeito de CLUSTERse deteriora com gravações posteriores na tabela da mesma maneira (e permanece intacto enquanto você nunca DELETEou UPDATE- ou INSERTquebra a ordem desejada).

    Algumas respostas se concentram nesses efeitos de gravações posteriores e perdem o ponto da pergunta. A resposta para sua pergunta é basicamente:

    SIM , inserir em ordem tem o mesmo efeito que agrupar.

    com base em algumas condições:

    as consultas nesta tabela serão filtradas por uma coluna de ID de chave estrangeira.

    Isso significa que você acessa a linha com o mesmo ID de uma só vez, não um intervalo de IDs sequenciais. Então tudo que você precisa é de tuplas agrupadas por ID, a ordem física entre os IDs não tem sentido e é irrelevante.

    E:

    gerando esses dados em pedaços relacionados à chave estrangeira

    Ou seja, "pedaços" incluem todas as linhas para o mesmo ID em sequência. Não há outras linhas para o mesmo ID inserido mais cedo ou mais tarde. Então algo como:

    INSERT INTO big_table (source_table1_id,a,b,c)
    SELECT s1.source_table1_id, ... 
    FROM   source_table1 s1
    ...
    WHERE s1.source_table1_id BETWEEN 123 and 125 -- example
    ORDER BY s1.source_table1_id

    E:

    Eu nunca vou precisar UPDATEdele em uso normal; partes podem ser deletadas e regeneradas.

    A parte sobre DELETEé a única parte levemente problemática. Se você nunca excluísse também, estaria feito aqui. Se por "porções" você quer dizer todas as linhas com disse IDde uma vez, você ainda é bom, principalmente . Ao excluir e inserir na mesma transação, não há fragmentação nos IDs. (As tuplas excluídas ainda não estão "mortas" e não são substituídas na mesma transação.)

    Tuplas mortas começam a inchar a tabela e inserções posteriores podem começar a preencher buracos físicos, que é onde a fragmentação pode começar. O inchaço com tuplas mortas tem vários efeitos ruins acumulados, mas o acesso ao índice em todas as linhas para um determinado ID não é afetado.

    Mas tudo isso é ortogonal à sua pergunta, pois as mesmas considerações se aplicam a CLUSTER.

    Você já considerou pg_repack , que pode fazer o mesmo que CLUSTER, só que sem bloqueio exclusivo na tabela. Eles acabaram de adicionar o Postgres 9.6 à lista de versões suportadas esta semana.

    Relacionado:

    • Configurando o PostgreSQL para desempenho de leitura
    • Otimizando consultas em um intervalo de carimbos de data/hora (duas colunas)
    • 2
  3. Evan Carroll
    2017-01-21T20:37:40+08:002017-01-21T20:37:40+08:00

    Não, não.

    • O clustering é feito sobre um índice.
    • Sem um ORDER BY, o pedido de inserção pode ser totalmente aleatório
    • Com um ORDER BYan INSERTainda pode deixar lacunas porque não reescreve a tabela.
    • Cluster força uma reescrita de tabela.

    Considere isto..

    CREATE TABLE foo AS
    SELECT random() AS bar, random() AS quz
    FROM generate_series(1,100) AS t(x);
    

    Por implementação, isso insere as linhas na ordem em que foram geradas. Não é garantido, mas atualmente tem. O SQL não garante nada da ordem de retorno sem um ORDER BY. No entanto, os dados não professam nenhuma ordem útil quando gerados dessa forma, portanto, isso é meramente trivial e não significativo para o desempenho da consulta. Agora podemos fazer isso..

    CREATE INDEX foo_bar_idx ON foo(bar);
    CLUSTER foo USING foo_bar_idx;
    

    Agora as linhas fooestão ordenadas por bar, isso pode tornar certas operações mais rápidas que usam foo_bar_idx.

    O que acontece se essas linhas já estiverem nessa ordem. O que acontece se o índice se alinhar com a linha e o clustering não reordenar nada? Então nada acontece. Mas esse não é um caso de uso típico, mesmo sem INSERTe DELETE. No PostGIS, inserimos dados o tempo todo e agrupamos tabelas complexas de geometrias por sua caixa delimitadora . As comparações de caixa delimitadora são abstratas, mas tornam as coisas que as usam substancialmente mais rápidas.

    • 1
  4. jjanes
    2017-01-23T15:20:24+08:002017-01-23T15:20:24+08:00

    Se a tabela nunca for atualizada ou excluída, as linhas inseridas serão ordenadas fisicamente em sua ordem de inserção cronológica. Mas se ele for excluído ou atualizado, a limpeza da tabela criará buracos de espaço livre na tabela, e as linhas recém-inseridas podem ser espalhadas onde quer que se encaixem nesses buracos. Isso seria um problema menor se as exclusões ocorrerem em grandes conjuntos de dados especificados por um intervalo na mesma coluna pela qual você deseja classificar. Nesse caso, páginas inteiras de dados serão excluídas juntas, liberando esse espaço para serem reutilizados em conjunto.

    É improvável que seu INSERT INTO...SELECT...ORDER BY seja eficaz, porque a ordenação ocorrerá apenas em partes. A menos que seus pedaços sejam muito grandes, ou os próprios pedaços sejam processados ​​em ordem, bem como ordenados dentro de cada pedaço, é improvável que a ordenação de pedaços seja muito boa.

    Você pode olhar para o intervalo de particionamento de sua tabela na chave de classificação. Isso pode resolver o problema apenas mantendo valores semelhantes juntos. Caso contrário, pelo menos faria com que o CLUSTER de cada partição separada levasse muito menos tempo do que o CLUSTER de uma tabela gigante, o que pode tornar mais fácil agendá-los.

    • 1

relate perguntas

  • Sequências Biológicas do UniProt no PostgreSQL

  • Como determinar se um Índice é necessário ou necessário

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • 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