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 / 305649
Accepted
O. Jones
O. Jones
Asked: 2022-01-06 04:20:11 +0800 CST2022-01-06 04:20:11 +0800 CST 2022-01-06 04:20:11 +0800 CST

É necessário um índice exclusivo para um id sequencial (incremento automático)?

  • 772

Se uma coluna AUTO_INCREMENT sequencial não for também a chave primária de uma tabela MySQL, ela precisa ter seu próprio índice UNIQUE para garantir a integridade dos dados a longo prazo?

Estou trabalhando na reindexação de uma tabela MySQL específica para acelerar certas cláusulas WHERE muito comuns. A tabela é do CMS do WordPress . Sua definição fora da distribuição, simplificada, é essa.

CREATE TABLE wp_postmeta (
    meta_id BIGINT UNSIGNED AUTO_INCREMENT,
    post_id BIGINT UNSIGNED,
    meta_key VARCHAR(255),
    meta_value LONGTEXT,
    PRIMARY KEY (meta_id),
    INDEX post_id (post_id),
    INDEX meta_key (meta_key)
);

MariaDB / MySQL (InnoDB) agora usa índices clusterizados, então alterei o PK para este:

    PRIMARY KEY (post_id, meta_key, meta_id)

Isso significa que filtros WHERE como post_id = 42 AND meta_key = 'value'podem ser satisfeitos usando o índice clusterizado e a busca LONGTEXT. Está comprovado que resolve o problema de desempenho dos meus usuários.

A questão é esta: essa tabela reindexada também precisa de um índice exclusivo na coluna de ID de incremento automático para continuar funcionando corretamente a longo prazo? Ou posso omitir esse índice para economizar um pouco de espaço e desempenho de UPDATE/INSERT?

    UNIQUE INDEX meta_id (meta_id),

(Estou ciente de que pode haver designs de tabela muito melhores do que este. Mas minha atribuição atual não me permite alterar a tabela, apenas os índices.)

mysql index-tuning
  • 5 5 respostas
  • 435 Views

5 respostas

  • Voted
  1. O. Jones
    2022-01-06T04:49:45+08:002022-01-06T04:49:45+08:00

    Acontece que essa foi uma pergunta idiota. O DBMS não permitirá uma coluna de incremento automático sem um índice. Ele lança o erro 1075 nas tentativas de fazer isso.

    Por causa de outros padrões de filtro não mencionados na pergunta, vou com esses índices.

    PRIMARY KEY (post_id, meta_key, meta_id)
    UNIQUE INDEX meta_id (meta_id)
    INDEX meta_key (meta_key, meta_value(32), post_id)
    INDEX meta_value (meta_value(32))
    

    Os índices de prefixo estão na coluna LONGTEXT. Em meta_keyse eu pudesse fazer

    INDEX meta_key (meta_key, meta_value(32)) INCLUDE(post_id)
    

    Eu faria, mas este RDBMS não INCLUDE () coisas em índices.

    • 2
  2. Best Answer
    ypercubeᵀᴹ
    2022-01-06T04:59:39+08:002022-01-06T04:59:39+08:00

    Você quer mudar PRIMARY KEYde

    PRIMARY KEY (meta_id)
    

    para

    PRIMARY KEY (post_id, meta_key, meta_id)
    

    Isso é permitido no mecanismo InnoDB, mas requer que você tenha um índice (não necessariamente UNIQUEligado (meta_id)ou um índice com mais colunas e meta_idcomo a primeira coluna.


    Então, respondendo a última pergunta:

    Ou posso omitir esse índice para economizar um pouco de espaço e desempenho de UPDATE/INSERT?

    Não, você ainda precisará de um índice no meta_id e (único ou não) do espaço extra.


    Reclassificando a pergunta sobre integridade:

    Se uma coluna AUTO_INCREMENT sequencial não for também a chave primária de uma tabela MySQL, ela precisa ter seu próprio índice UNIQUE para garantir a integridade dos dados a longo prazo ?

    Isso realmente depende se a exclusividade é necessária para o (meta_id). Você terá que verificar se algum outro procedimento do WordPress e seu aplicativo dependem de (meta_id) ser exclusivo.

    Caso contrário, você não precisa ter o índice como UNIQUE.

    Como precaução, porém, sugiro que você o mantenha como ÚNICO. Você nunca sabe se em alguns anos, você ou o próximo desenvolvedor decide mudar o PK de volta para o padrão ou se você adiciona um plugin que quebra com valores meta_id não exclusivos. Ou mude para uma plataforma diferente e ter esses recursos exclusivos simplifica a migração.


    Voltando a economizar espaço, você pode considerar que com o novo PK com 3 colunas, qualquer outro índice secundário (único ou não) tem todas essas 3 colunas incluídas também.

    Então seus índices:

    PRIMARY KEY (post_id, meta_key, meta_id),
    UNIQUE INDEX (meta_id),
    INDEX post_id (post_id),
    INDEX meta_key (meta_key)
    

    são realmente (sob o capô):

    PRIMARY KEY (post_id, meta_key, meta_id),
    UNIQUE INDEX (meta_id) INCLUDE (post_id, meta_key),
    INDEX post_id (post_id) INCLUDE (meta_key, meta_id),
    INDEX meta_key (meta_key) INCLUDE (post_id, meta_id)
    

    O post_idíndice é, portanto, redundante e você pode eliminá-lo sem nenhuma perda. Qualquer consulta que antes usasse o post_id, agora pode usar o PK.

    Re: comprimento do PK. Se houver exatamente um índice secundário, o espaço em disco necessário ao ter PRIMARY KEY(id), INDEX(foo, bar)é quase idêntico ao espaço para arquivos PRIMARY KEY(foo, bar, id), INDEX(id).

    Se houver mais de um índice secundário, um PK maior levará a mais espaço em disco.

    • 2
  3. Bill Karwin
    2022-01-06T14:05:18+08:002022-01-06T14:05:18+08:00

    Resposta curta: no InnoDB, a coluna de incremento automático deve ser a coluna mais à esquerda de algum índice, seja o índice de chave primária (agrupado), ou algum índice secundário. Não precisa ser uma chave exclusiva, qualquer índice de árvore B serve.

    O seguinte não é válido...

    PRIMARY KEY (post_id, meta_key, meta_id)
    

    a menos que outro índice (também conhecido como chave) seja definido com meta_id como a coluna mais à esquerda.

    KEY (meta_id)
    

    Como uma coluna de incremento automático é naturalmente única por si só, é incomum criar uma chave primária ou exclusiva da coluna de incremento automático junto com outras colunas.

    • 1
  4. Rick James
    2022-01-06T15:12:17+08:002022-01-06T15:12:17+08:00
    INDEX(meta_id) 
    

    É o mínimo necessário para satisfazer o MySQL. (Como mencionado em outras respostas.)

    No entanto, isso permite que o usuário adicione explicitamentemeta_id um valor duplicado para . Presumivelmente , o WP nunca faz essa coisa 'burra'.

    UNIQUE(meta_id)
    

    Desacelera um INSERTspouco -- porque a inserção não retornará ao cliente até que a exclusividade seja verificada. Com um plain INDEX(meta_id), o Insert coloca a atualização desse índice no "buffer de alteração" para armazenamento posterior no BTree para esse índice secundário.

    Outra diferença entre UNIQUEe INDEXvem quando SELECTingpor um valor específico para meta_id. Com INDEX, a consulta continua lendo linhas, procurando mais linhas com o mesmo meta_id. Por outro lado, UNIQUEpode parar depois de acertar a primeira ocorrência.

    Nenhuma dessas "diferenças" vale a pena se preocupar ao se preocupar com o desempenho. Estou apenas mencionando-os para completar.

    • 1
  5. J.D.
    2022-01-06T04:46:06+08:002022-01-06T04:46:06+08:00

    Depende do que você quer dizer com " continuar funcionando corretamente a longo prazo "? Um índice exclusivo só fará seu trabalho de impedir que valores duplicados sejam inseridos, independentemente de o campo ter uma especificação de incremento automático ou não. Mas isso não impede que alguém insira manualmente um valor fora de sequência exclusivo no meta_idcampo.

    • 0

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

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

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

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