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 / 17926
Accepted
Radu Murzea
Radu Murzea
Asked: 2012-05-16 23:42:40 +0800 CST2012-05-16 23:42:40 +0800 CST 2012-05-16 23:42:40 +0800 CST

Por que o InnoDB não armazena a contagem de linhas?

  • 772

Todo mundo sabe que, em tabelas que usam o InnoDB como motor, consultas do tipo SELECT COUNT(*) FROM mytablesão muito inexatas e muito lentas, principalmente quando a tabela fica maior e há constantes inserções/exclusões de linhas enquanto a consulta é executada.

Pelo que entendi, o InnoDB não armazena a contagem de linhas em uma variável interna, que é o motivo desse problema.

Minha pergunta é: Por que isso acontece? Seria tão difícil armazenar tais informações? É uma informação importante saber em muitas situações. A única dificuldade que vejo se tal contagem interna seria implementada é quando as transações estão envolvidas: se a transação não for confirmada, você conta as linhas inseridas por ela ou não?

PS: Não sou especialista em DBs, sou apenas alguém que tem o MySQL como um simples hobby. Portanto, se acabei de perguntar algo estúpido, não seja excessivamente crítico: D .

mysql innodb
  • 3 3 respostas
  • 8599 Views

3 respostas

  • Voted
  1. Remus Rusanu
    2012-05-17T00:02:33+08:002012-05-17T00:02:33+08:00

    Para iniciantes, não existe a 'contagem atual' para armazenar em uma variável. Uma consulta como SELECT COUNT(*) FROM ...está sujeita ao nível de isolamento atual e a todas as transações pendentes simultâneas. Dependendo do nível de isolamento, a consulta pode ver ou não linhas inseridas ou excluídas por transações pendentes não confirmadas. A única maneira de responder é contar as linhas visíveis para a transação atual.

    Observe que nem toquei no assunto ainda mais espinhoso das transações simultâneas que começam ou terminam durante a contagem. Sem falar nos retrocessos...

    • 16
  2. Best Answer
    RolandoMySQLDBA
    2012-05-17T07:33:36+08:002012-05-17T07:33:36+08:00

    Eu concordo com @RemusRusanu (+1 para sua resposta)

    SELECT COUNT(*) FROM mydb.mytableno InnoDB se comporta como um mecanismo de armazenamento transacional deveria. Compare-o com o MyISAM.

    MyISAMGenericName

    Se mydb.mytablefor uma tabela MyISAM, iniciar SELECT COUNT(*) FROM mydb.mytable;é como executar arquivos SELECT table_rows FROM information_schema.table WHERE table_schema = 'mydb' AND table_name = 'mytable';. Isso aciona uma pesquisa rápida da contagem de linhas no cabeçalho da tabela MyISAM.

    InnoDBGenericName

    Se mydb.mytablefor uma tabela InnoDB, você obtém uma miscelânea de coisas acontecendo. Você tem MVCC acontecendo, governando o seguinte:

    • ib_logfile0/ib_logfile1 (Redo Logs)
    • ibdata1
      • Desfazer registros
      • Reversões
      • Alterações no Dicionário de Dados
    • Gerenciamento de pool de buffers
    • Isolamento de transação (4 tipos)
      • Leituras repetíveis
      • Ler confirmado
      • Ler não confirmado
      • serializável

    Pedir ao InnoDB uma contagem de tabelas requer navegação por essas coisas sinistras. Na verdade, nunca se sabe se SELECT COUNT(*) from mydb.mytableconta apenas leituras repetíveis ou inclui leituras que foram confirmadas e aquelas que não foram confirmadas.

    Você pode tentar estabilizar um pouco as coisas habilitando innodb_stats_on_metadata .

    De acordo com a documentação do MySQL em innodb_stats_on_meta_data

    Quando esta variável está habilitada (que é o padrão, como antes da variável ser criada), o InnoDB atualiza as estatísticas durante as declarações de metadados, como SHOW TABLE STATUS ou SHOW INDEX, ou ao acessar as tabelas INFORMATION_SCHEMA TABLES ou STATISTICS. (Essas atualizações são semelhantes ao que acontece com ANALYZE TABLE.) Quando desativado, o InnoDB não atualiza as estatísticas durante essas operações. Desabilitar esta variável pode melhorar a velocidade de acesso para esquemas que possuem um grande número de tabelas ou índices. Também pode melhorar a estabilidade dos planos de execução para consultas que envolvem tabelas InnoDB.

    Desativá-lo pode ou não fornecer uma contagem mais estável em termos de configuração de planos EXPLAIN. Isso pode afetar o desempenho de SELECT COUNT(*) from mydb.mytableuma maneira boa, ruim ou não. Experimente e veja!!!

    • 9
  3. Marcus Adams
    2012-05-17T10:32:40+08:002012-05-17T10:32:40+08:00

    Embora teoricamente seja possível manter uma contagem precisa do número de linhas para uma determinada tabela com o InnoDB, isso custaria muitos bloqueios, o que afetaria negativamente o desempenho. Também seria diferente com base no nível de isolamento.

    O MyISAM já faz bloqueio de nível de tabela, então não há custo extra lá.

    Eu raramente exijo uma contagem de linhas para uma tabela, embora eu use COUNT(*) bastante. Eu geralmente tenho uma cláusula WHERE anexada. Usando um índice eficiente em um pequeno conjunto de resultados, acho que eles são rápidos o suficiente.

    Discordo que as contagens sejam imprecisas. As contagens representam um instantâneo dos dados e sempre as achei exatas.

    Resumindo, o MySQL deixa que você implemente isso para o InnoDB. Você pode armazenar uma contagem e incrementá-la/diminuí-la após cada consulta. Porém, a solução mais fácil é provavelmente mudar para MyISAM.

    • 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

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 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

    Como selecionar a primeira linha de cada grupo?

    • 6 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
    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
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +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
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +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