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 / 217087
Accepted
Erwin Brandstetter
Erwin Brandstetter
Asked: 2018-09-09 07:56:16 +0800 CST2018-09-09 07:56:16 +0800 CST 2018-09-09 07:56:16 +0800 CST

Por que *não* ERRO: o tamanho da linha do índice xxxx excede o máximo de 2712 para o índice "foo"?

  • 772

Temos visto repetidamente tentativas fracassadas de indexar colunas com valores que excedem um tamanho máximo. O Postgres 10 tem esse tipo de mensagem de erro:

ERROR:  index row size xxxx exceeds maximum 2712 for index "foo_idx"
HINT:  Values larger than 1/3 of a buffer page cannot be indexed.
       Consider a function index of an MD5 hash of the value, or use full text indexing.

Exemplos:

  • Sobrecarga de índice variável de caracteres e limite de comprimento
  • Erro de tamanho máximo da linha do índice

etc.

Agora, a_horse_with_no_name demonstrou um caso com valores muito maiores text(10.000 caracteres) que ainda parece funcionar com um UNIQUEíndice no Postgres 9.6. Citando seu caso de teste:

create table tbl (col text);
create unique index on tbl (col);

insert into tbl
values (rpad(md5(random()::text), 10000, md5(random()::text)));

select length(val) from x;  -- 10000

Nenhum erro e o valor da coluna realmente testado com um comprimento de 10.000 caracteres.

Houve mudanças recentes ou como isso é possível?

postgresql index
  • 1 1 respostas
  • 9714 Views

1 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2018-09-09T08:17:47+08:002018-09-09T08:17:47+08:00

    Resposta curta: compressão.

    O tipo de dados textpermite compactação (sem perdas!) e armazenamento fora de linha por padrão:

    SELECT typstorage FROM pg_type WHERE typname = 'text';  -- 'x'
    

    O manual sobre pg_type.typstorage:

    p: Value must always be stored plain.
    e: Value can be stored in a “secondary” relation (if relation has one, see pg_class.reltoastrelid).
    m: Value can be stored compressed inline.
    x: Value can be stored compressed inline or stored in “secondary” storage.
    

    xé a escolha usual para tipos torrados. Observe que mos valores também podem ser movidos para o armazenamento secundário, mas apenas como último recurso ( e e xos valores são movidos primeiro).

    Teste com pg_column_size()em vez de length(). Certifique-se de testar as colunas reais da tabela (com compactação aplicada) e não apenas os valores de entrada. Ver:

    CREATE TABLE tbl (id int, col text);
    INSERT INTO tbl(id, col) VALUES 
       (1, rpad(md5('non_random'::text),     100, md5('non_random'::text)))
     , (2, rpad(md5('non_random'::text),    1000, md5('non_random'::text)))
     , (3, rpad(md5('non_random'::text),   10000, md5('non_random'::text)))
     , (4, rpad(md5('non_random'::text),  100000, md5('non_random'::text)))
     , (5, rpad(md5('non_random'::text),  500000, md5('non_random'::text)))
     , (6, rpad(md5('non_random'::text), 1000000, md5('non_random'::text))); 
    
    SELECT id, left(col, 10) || ' ...' AS col
         , length(col) AS char_length
         , pg_column_size(col) AS compressed
         , pg_column_size(col || '') AS uncompressed
    FROM   tbl ORDER BY id; 
    
    id | col            | char_length | compressed | uncompressed
    ---+----------------+-------------+------------+-------------
     1 | 67ad0f29fa ... |         100 |        101 |          104
     2 | 67ad0f29fa ... |        1000 |       1004 |         1004
     3 | 67ad0f29fa ... |       10000 |        160 |        10004
     4 | 67ad0f29fa ... |      100000 |       1191 |       100004
     5 | 67ad0f29fa ... |      500000 |       5765 |       500004
     6 | 67ad0f29fa ... |     1000000 |      11487 |      1000004
    
    SELECT pg_column_size(rpad(md5('non_random'::text), 1000000, md5('non_random'::text)));
    
    pg_column_size
    --------------
           1000004
    

    db<>fique aqui

    Observe como o valor é forçado a ser descompactado de seu formato de armazenamento com a expressão noop: pg_column_size(col || '').

    A 5ª linha seria muito grande para caber na tupla do índice (mesmo com compactação) e acionaria a mensagem de erro no título.

    A 6ª linha seria grande demais para caber até mesmo na página de índice e acionar a mensagem de erro relacionada:

    ERRO: a linha do índice requer 11504 bytes, o tamanho máximo é 8191

    Os valores de teste gerados com rpad()padrões de repetição, que permitem compactação massiva. Mesmo cordas muito longas ainda se encaixam facilmente no max. tamanho após a compressão desta forma.

    Relacionado:

    • Qual é a sobrecarga para varchar(n)?

    Resposta longa

    Executei testes mais extensos, adulterando os internos de armazenamento para verificar meu entendimento. Apenas para fins de teste!

    • db<>fique aqui

    dbfiddle não permite acesso de gravação aos catálogos do sistema. Mas as consultas estão aí para tentar "em casa".

    • 16

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