O MySQL pode razoavelmente executar consultas em bilhões de linhas?


283

Estou pensando em armazenar varreduras de um espectrômetro de massa em um banco de dados MySQL e gostaria de saber se armazenar e analisar essa quantidade de dados é remotamente viável. Sei que o desempenho varia muito dependendo do ambiente, mas estou procurando uma ordem aproximada de magnitude: as consultas levarão 5 dias ou 5 milissegundos?

Formato de entrada

Cada arquivo de entrada contém uma única execução do espectrômetro; cada execução é composta por um conjunto de varreduras e cada varredura possui uma matriz ordenada de pontos de dados. Existem alguns metadados, mas a maioria do arquivo é composta de matrizes de 32 ou 64 bits ou flutuações.

Sistema host

| ---------------- + ------------------------------- |
| OS Windows 2008 de 64 bits |
| Versão do MySQL | 5.5.24 (x86_64) |
| CPU 2x Xeon E5420 (total de 8 núcleos) |
| RAM 8GB |
| Sistema de arquivos SSD | 500 GiB |
| RAID HDD | 12 TiB |
| ---------------- + ------------------------------- |

Existem alguns outros serviços em execução no servidor usando um tempo insignificante do processador.

Estatísticas do arquivo

| ------------------ + -------------- |
| número de arquivos | ~ 16.000 |
| tamanho total | 1,3 TiB |
| tamanho mínimo | 0 bytes |
| tamanho máximo | 12 GiB |
| significa | 800 MiB |
| mediana | 500 MiB |
| pontos de dados totais | ~ 200 bilhões |
| ------------------ + -------------- |

O número total de pontos de dados é uma estimativa muito aproximada.

Esquema proposto

Estou planejando fazer as coisas "corretamente" (ou seja, normalizar os dados como loucos) e, portanto, teria uma runstabela, uma spectratabela com uma chave estrangeira para runse uma datapointstabela com uma chave estrangeira para spectra.

A questão dos 200 bilhões de pontos de dados

Vou analisar vários espectros e possivelmente várias execuções, resultando em consultas que podem tocar milhões de linhas. Supondo que eu indexe tudo corretamente (que é um tópico para outra pergunta) e não estou tentando embaralhar centenas de MiB pela rede, é remotamente plausível para o MySQL lidar com isso?

informação adicional

Os dados da varredura serão provenientes de arquivos no formato mzML baseado em XML . A carne desse formato está nos <binaryDataArrayList>elementos em que os dados são armazenados. Cada varredura produz> = 2 <binaryDataArray>elementos que, juntos, formam uma matriz bidimensional (ou mais) do formulário [[123.456, 234.567, ...], ...].

Esses dados são gravados uma vez, portanto, o desempenho da atualização e a segurança das transações não são preocupações.

Meu plano ingênuo para um esquema de banco de dados é:

runs mesa

| nome da coluna | tipo |
| ------------- + ------------- |
| id | CHAVE PRIMÁRIA |
| start_time | TIMESTAMP |
| nome | VARCHAR
| ------------- + ------------- |

spectra mesa

| nome da coluna | tipo |
| ---------------- + ------------- |
| id | CHAVE PRIMÁRIA |
| nome | VARCHAR
| índice | INT
| spectrum_type | INT
| representação | INT
| run_id | CHAVE ESTRANGEIRA |
| ---------------- + ------------- |

datapoints mesa

| nome da coluna | tipo |
| ------------- + ------------- |
| id | CHAVE PRIMÁRIA |
| spectrum_id | CHAVE ESTRANGEIRA |
| mz | DUPLO |
| num_counts | DUPLO |
| índice | INT
| ------------- + ------------- |

Isso é razoável?


Então, como você pode deduzir, sou o programador, não o biólogo do laboratório, por isso não conheço a ciência tão bem quanto os cientistas de verdade.

Aqui está um gráfico de um único espectro (varredura) do tipo de dados com o qual tratarei:

Captura de tela do visualizador

O objetivo do software é descobrir onde e quão significativos são os picos. Usamos um pacote de software proprietário para descobrir isso agora, mas queremos escrever nosso próprio programa de análise (em R) para saber o que diabos está acontecendo embaixo das folhas. Como você pode ver, a grande maioria dos dados é desinteressante, mas não queremos descartar dados potencialmente úteis que nosso algoritmo perdeu. Depois que tivermos uma lista de picos prováveis ​​com os quais estamos satisfeitos, o restante do pipeline usará essa lista de picos, em vez da lista bruta de pontos de dados. Suponho que seria suficiente armazenar os pontos de dados brutos como um grande blob, para que eles possam ser analisados ​​novamente, se necessário, mas mantenha apenas os picos como entradas distintas do banco de dados. Nesse caso, haveria apenas algumas dúzias de picos por espectro, então o material de escala maluco não deveria



8
Como se trata de dados brutos do espectrômetro de massa A / D, parece realmente estúpido armazená-los no banco de dados. Eu pegava meus dados brutos, os despejava, processava e armazenava os RESULTADOS processados ​​em um banco de dados. Os resultados seriam (a) formas de onda armazenadas uma forma de onda por linha, (b) outros dados associados a essas formas de onda, como curvas de calibração, e (c) linhas de resultados no banco de dados. Isso reduziria bilhões de linhas de inchaço do seu design. Quando você deseja executar novamente uma análise inicial, efetivamente editaria alguns parâmetros, executaria uma operação gigante de computação e armazenaria os novos resultados no banco de dados.
21812 Warren P

Respostas:


115

Não estou muito familiarizado com suas necessidades, mas talvez armazenar cada ponto de dados no banco de dados seja um pouco exagerado. Parece quase como adotar a abordagem de armazenar uma biblioteca de imagens, armazenando cada pixel como um registro separado em um banco de dados relacional.

Como regra geral, o armazenamento de dados binários em bancos de dados está errado na maioria das vezes. Geralmente, há uma maneira melhor de resolver o problema. Embora não seja inerentemente errado armazenar dados binários no banco de dados relacional, muitas vezes as desvantagens superam os ganhos. Os bancos de dados relacionais, como o nome faz alusão, são mais adequados para armazenar dados relacionais. Dados binários não são relacionais. Ele adiciona tamanho (geralmente significativamente) aos bancos de dados, pode prejudicar o desempenho e levar a perguntas sobre a manutenção de instâncias do MySQL com bilhões de registros. A boa notícia é que existem bancos de dados especialmente adequados para armazenar dados binários. Um deles, embora nem sempre seja aparente, é o seu sistema de arquivos! Basta criar uma estrutura de nomes de diretório e arquivos para seus arquivos binários,

Outra abordagem seria usar um sistema de armazenamento baseado em documentos para seus dados de pontos de dados (e talvez espectros) e usar o MySQL para as execuções (ou talvez colocar as execuções no mesmo banco de dados que os outros).


5
Por que é considerado errado armazenar dados binários em um banco de dados? (Perguntando parcialmente porque eu sou curioso, mas também porque eu posso pensar em um caso de uso para ele.)

15
Se os dados binários não tiverem valor individualmente, não deverão ser armazenados como uma linha exclusiva. O pixel 500x325 em uma imagem é irrelevante.

1
Esse é um ponto muito bom. Provavelmente, devemos manter os arquivos brutos por perto, caso precisemos extrair as coisas novamente mais tarde, mas a analogia com o armazenamento de imagens é ótima. Como nunca precisaremos acessar cada ponto de dados (a menos que refizemos a extração de pico), simplesmente armazenar as informações estatísticas extraídas seria muito melhor.
haxney

107

Certa vez, trabalhei com um banco de dados MySQL muito grande (Terabyte +). A maior mesa que tínhamos tinha literalmente mais de um bilhão de linhas. Como estava usando o MySQL 5.0, é possível que as coisas tenham melhorado.

Funcionou. O MySQL processou os dados corretamente na maioria das vezes. Era extremamente pesado, no entanto. (Se você deseja disponibilidade no nível sigma com um terabyte de dados, não use o MySQL. Éramos uma startup que não tinha DBA e recursos limitados.)

Apenas fazer backup e armazenar os dados era um desafio. Levaria dias para restaurar a tabela, se necessário.

Tínhamos várias tabelas na faixa de 10 a 100 milhões de linhas. Quaisquer junções significativas nas tabelas consumiam muito tempo e levariam uma eternidade. Por isso, escrevemos procedimentos armazenados para 'caminhar' pelas tabelas e processar junções contra intervalos de 'id'. Dessa maneira, processaríamos os dados de 10 a 100.000 linhas por vez (junte-se aos 1-100.000 dos IDs e 100.001-200.000, etc.). Isso foi significativamente mais rápido do que juntar-se a toda a tabela.

Usar índices em tabelas muito grandes que não são baseadas na chave primária também é muito mais difícil. O Mysql 5.0 armazena índices em duas partes - armazena índices (exceto o índice primário) como índices nos valores da chave primária. Portanto, pesquisas indexadas são feitas em duas partes: primeiro o MySQL acessa um índice e extrai os valores da chave primária que ele precisa encontrar; em seguida, faz uma segunda pesquisa no índice da chave primária para descobrir onde estão esses valores.

O motivo disso é que, para tabelas muito grandes (de 1 a 200 milhões de linhas), a indexação em tabelas é mais restritiva. Você precisa de menos índices mais simples. E fazer instruções simples de seleção que não estejam diretamente em um índice pode nunca voltar. Onde as cláusulas devem atingir índices ou esquecê-las.

Mas tudo o que foi dito, as coisas realmente funcionaram. Conseguimos usar o MySQL com essas tabelas muito grandes, fazer cálculos e obter respostas corretas.

Tentar fazer a análise de 200 bilhões de linhas de dados exigiria hardware muito sofisticado e muita paciência e paciência. Apenas manter os dados armazenados em backup em um formato do qual você possa restaurar seria um trabalho significativo.

Concordo com a resposta de srini.venigalla de que normalizar dados como loucos pode não ser uma boa ideia aqui. Fazer junções em várias tabelas com tantos dados abrirá você para o risco de classificação de arquivos, o que poderia significar que algumas de suas consultas simplesmente nunca voltariam. A desormallização com chaves inteiras simples daria uma chance maior de sucesso.

Tudo o que tínhamos era InnoDB. Em relação ao MyISAM vs. InnoDB: O principal seria não misturar os dois. Você não pode realmente otimizar um servidor para ambos devido à maneira como o MySQL armazena em cache chaves e outros dados. Escolha uma ou outra para todas as tabelas em um servidor, se puder. O MyISAM pode ajudar com alguns problemas de velocidade, mas pode não ajudar com o trabalho geral do DBA que precisa ser feito - o que pode ser um assassino.


1
O MySQL melhorou bastante no departamento de índices (...) desde o 5.0. Seria interessante ver como ele se comporta agora.
Ring Ø

70

normalizando os dados como loucos

Normalizar os dados como loucos pode não ser a estratégia certa neste caso. Mantenha suas opções em aberto armazenando os dados no formulário Normalizado e também na forma de visualizações materializadas altamente adequadas ao seu aplicativo. A chave desse tipo de aplicativo NÃO é a gravação de consultas ad-hoc. A modelagem de consultas é mais importante que a modelagem de dados. Comece com suas consultas de destino e trabalhe em direção ao modelo de dados ideal.

Is this reasonable?

Eu também criaria uma tabela plana adicional com todos os dados.

run_id | spectrum_id | data_id | <data table columns..> |

Vou usar esta tabela como a principal fonte de todas as consultas. O motivo é evitar ter que fazer junções. Associações sem indexação tornarão seu sistema muito inutilizável, e ter índices em arquivos tão grandes será igualmente terrível.

A estratégia é: consultar a tabela acima primeiro, despejar os resultados em uma tabela temporária e associar a tabela temporária às tabelas de pesquisa de Run e Spectrum e obter os dados desejados.


Você analisou suas necessidades de gravação versus leitura? Será muito tentador abandonar o SQL e usar mecanismos de armazenamento de dados não padrão. Na minha opinião, deveria ser o último recurso.

Para acelerar as velocidades de gravação, experimente o método Handler Socket. Percona, se bem me lembro, empacota o Handler Socket no pacote de instalação. (nenhuma relação com Percona!)

http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html


33

A resposta curta é um sim qualificado - à medida que o número de linhas cresce, o esquema preciso, os tipos de dados e as operações que você escolhe aumentam em importância.

O quanto você normaliza seus dados depende das operações que planeja executar nos dados armazenados. Sua tabela de 'pontos de dados', em particular, parece problemática - você está planejando comparar o enésimo ponto de um dado espectro com o mésimo de qualquer outro? Caso contrário, armazená-los separadamente pode ser um erro. Se seus pontos de dados não ficarem sozinhos, mas fizerem sentido apenas no contexto de seus espectros associados, você não precisará de uma PRIMARY KEY - uma chave estrangeira para os espectros e uma coluna 'enésima' (sua coluna 'index'?) Será suficiente .

Defina as operações inter e intra-espectro que você deve executar e, em seguida, descubra a maneira mais barata de realizá-las. Se a igualdade é tudo o que é necessário, elas podem ser desnormalizadas - possivelmente com alguns metadados estatísticos pré-calculados que auxiliam suas operações. Se você precisar absolutamente de acesso in-SQL a pontos de dados individuais, reduza o tamanho de cada linha para o número mínimo de campos e o menor tipo de dados possível.

O maior MySQL que já gerenciei pessoalmente foi de ~ 100 milhões de linhas. Nesse tamanho, você deseja manter suas linhas e, portanto, seus campos em tamanho fixo - isso permite que o MySQL calcule com eficiência a posição de qualquer linha na tabela multiplicando o tempo do tamanho fixo de cada linha (pense na aritmética do ponteiro) - embora o os detalhes exatos dependem de qual mecanismo de armazenamento você planeja usar. Use o MyISAM se você conseguir se safar, o que falta na confiabilidade que compensa na velocidade e, na sua situação, deve ser suficiente. Substitua os campos de tamanho variável, como VARCHAR, por CHAR (n) e use RTRIM () em suas consultas de leitura.

Uma vez que suas linhas da tabela tenham largura fixa, você poderá reduzir o número de bytes, avaliando cuidadosamente os tipos de dados inteiros do MySQL (alguns dos quais não são padrão). Cada economia de 1 byte que você pode obter convertendo um INT de 4 bytes em um MEDIUMINT de 3 bytes economiza ~ 1 MB por milhão de linhas - o que significa menos E / S de disco e armazenamento em cache mais eficaz. Use os menores tipos de dados possíveis com os quais você pode se safar . Avalie com cuidado os tipos de ponto flutuante e veja se você pode substituir DOUBLEs de 8 bytes por FLOATs de 4 bytes ou mesmo NUMERICs de ponto fixo de <8 bytes . Execute testes para garantir que o que você escolher não o morderá mais tarde.

Dependendo das propriedades esperadas do seu conjunto de dados e das operações necessárias, pode haver economia adicional em codificações mais incomuns dos seus valores (padrões / repetições esperados que podem ser codificados como um índice em um conjunto de valores, dados brutos que podem apenas contribuir significativamente para metadados e descartados, etc.) - embora otimizações exóticas, não intuitivas e destrutivas só valham a pena quando todas as outras opções foram tentadas.

Mais importante, não importa o que você acabe fazendo, não assuma que você escolheu o esquema perfeito e comece a colocar cegamente 10s de milhões de registros. Bons projetos levam tempo para evoluir. Crie um conjunto grande, mas gerenciável (por exemplo, de 1 a 5%) de dados de teste e verifique a correção e o desempenho do seu esquema. Veja como as operações diferentes são executadas (http://dev.mysql.com/doc/refman/5.0/en/using-explain.html) e verifique se você equilibra seu esquema para favorecer as operações mais frequentes.

Eu disse curta? Ops. De qualquer forma, boa sorte!


23

Parece que o único motivo para fragmentar os dados do ponto de dados fora do XML (em oposição aos metadados como hora e tipo de execução) e para um formulário de banco de dados é quando você está analisando os espectros através de matrizes - ou seja, talvez encontrando tudo corre com uma certa assinatura. No momento, você já conhece o domínio do seu problema, mas isso pode ser semelhante ao armazenamento de músicas amostradas a 96kHz com 1 amostra por linha. Não tenho certeza se o tamanho é o problema mais do que como os dados são usados. Consultar os dados seria equivalente a pedir a amplitude relativa de 2 minutos na música em todas as músicas dos Beatles. Se você conhece o tipo de análise que pode ser executada, é bem possível que isso seja realizado nos sinais e armazenado nos metadados sobre a execução, faça mais sentido.

Também não tenho certeza se os dados de origem são escassos. É completamente possível que um espectro no banco de dados inclua apenas entradas diferentes de zero, enquanto o XML original inclui entradas zero e, portanto, o número total de linhas pode ser muito menor do que nos dados de origem.

Portanto, como muitas perguntas, antes de perguntar sobre o MySQL manipular seu modelo, voltar atrás e olhar para o modelo e como ele será usado é provavelmente mais apropriado do que se preocupar com o desempenho ainda.


Depois de revisar as atualizações de suas perguntas, acho que um modelo em que os dados binários são armazenados como um BLOB ou apenas um ponteiro para o arquivo é suficiente e trabalhamos para modificar o seu modelo para armazenar dados sobre os picos significativos que foram identificados quando os dados são primeiro. ler.


18

Eu administro um serviço de análise da web com cerca de 50 servidores de banco de dados, cada um contendo muitas tabelas com mais de 100 milhões de linhas e várias que tendem a ter mais de um bilhão de linhas, às vezes até dois bilhões (em cada servidor).

O desempenho aqui é bom. São dados muito normalizados. No entanto - minha principal preocupação com a leitura disso é que você estará bem acima da marca de 4,2 bilhões de linhas para essas tabelas (talvez não "execute", mas provavelmente as outras duas), o que significa que você precisará usar BIGINT em vez de INT para as chaves primárias / estrangeiras.

O desempenho do MySQL com campos BIGINT em uma coluna indexada é ridiculamente horrível comparado ao INT. Cometi o erro de fazer isso uma vez com uma tabela que pensei que poderia crescer desse tamanho e, uma vez que atingiu algumas centenas de milhões de linhas, o desempenho foi simplesmente péssimo. Não tenho números brutos, mas quando digo mal, quero dizer ruim para o Windows ME.

Esta coluna foi a chave primária. Nós o convertemos novamente em apenas um INT e presto magico, o desempenho foi bom novamente.

Todos os nossos servidores na época estavam no Debian 5 e no MySQL 5.0. Desde então, atualizamos para o Debian 6 e o ​​Percona MySQL 5.5, então as coisas podem ter melhorado desde então. Mas com base na minha experiência aqui, não, não acho que funcione muito bem.


17

Se funciona ou não, você sempre encontrará o mesmo problema com um único meio de armazenamento monolítico: os discos são lentos. A 100 MB / s (muito bom para mídia giratória), leva 3 horas apenas para ler uma tabela de 1 TB; isso pressupõe que nenhuma análise, busca ou outros atrasos o atrapalhem.

É por isso que quase todas as instalações de "big data" usam algum tipo de armazenamento de dados distribuído. Você pode gastar 8 vezes mais dinheiro construindo um computador super incrível para executar seu banco de dados, mas se você tiver muitos dados que podem ser digitalizados em paralelo, é quase sempre melhor distribuir a carga nos 8 computadores mais baratos.

Projetos como o hadoop foram criados especificamente para propósitos como este. Você cria um cluster de um monte de computadores baratos, distribui os dados por todos eles e os consulta em paralelo. É apenas uma dentre meia dúzia de soluções, todas construídas com base nessa mesma idéia, mas é muito popular.


13

Hm ... vejo muitas razões para você escolher esse tipo de estrutura de dados:

  • você realmente precisa fazer qualquer ponto de dados x quaisquer consultas de ponto de dados
  • você pretende executar toda a sua lógica no SQL

Agora, sugiro que você analise detalhadamente seus requisitos e verifique se pelo menos uma das suposições acima é verdadeira. Se nenhum deles é verdade, você está apenas tornando as coisas mais lentas. Para esse tipo de conjunto de dados, sugiro primeiro descobrir como os dados devem ser acessados, que tipo de precisão você precisará etc. - e depois projetar seu banco de dados em torno deles.

PS: Lembre-se de que você precisará de pelo menos 36 + 5 bytes por ponto de dados, portanto, com pontos de dados de 200B que devem fornecer pelo menos 8,2 TB de espaço necessário.

PPS: você não precisa da idcoluna da datapointstabela, PRIMARY KEY (spectrum_id, index)provavelmente é suficiente (apenas tome cuidado com indexa palavra reservada)


12

EDITAR:

NÃO FAÇA ISSO NO MYSQL COM DADOS ARMAZENADOS EM UM ÚNICO DISCO. Apenas ler essa quantidade de dados de um único meio levará horas. Você precisa ESCALAR, NÃO ACIMA.

E você precisa desnormalizar seus dados se quiser fazer uma análise de dados eficaz. Você não está projetando um sistema online aqui. Você deseja triturar números, projetar de acordo.

Resposta original abaixo da linha.


A resposta irá variar dependendo das suas perguntas, o MySQL pode não ser a melhor ferramenta para este trabalho. Você pode querer procurar uma solução que possa ser ampliada e não ampliada. Se você estiver disposto a fazer algum esforço, talvez deva procurar uma solução Map Reduce, como o Hadoop.

Se você deseja fazer mais consultas ad-hoc, a solução BigQuery do Google pode ser uma boa opção para você. Apresentação relevante do Google I / O 2012: Analisando Big Data com BigQuery

Portanto, a solução dependerá se isso é algo único e se você deseja oferecer suporte a consultas ad hoc razoavelmente.


9

Ninguém mencionou, portanto, minha sugestão. Dê uma olhada nas soluções MySQL massivamente fragmentadas . Por exemplo, veja esta apresentação tumblr altamente considerada .

O conceito é:

  • Em vez de um banco de dados extra grande
  • Use muitos pequenos contendo partes dos dados originais

Assim, você pode escalar horizontalmente, em vez de tentar melhorar o desempenho vertical. O BigTable e o GFS do Google também estão usando nós escaláveis ​​horizontalmente baratos para armazenar e consultar petabytes de dados.

No entanto, haverá problemas se você precisar executar consultas em diferentes fragmentos.


Se alguém estiver interessado, fiz um pedido de fragmento olá mundo há um tempo atrás. É discutido aqui em uma postagem no blog. Usei o RavenDB e o C #, mas os detalhes são irrelevantes e a ideia é a mesma.


7

Em que tipo de máquina os dados serão armazenados? É um dispositivo de armazenamento compartilhado?

O fator final que ditará o tempo de sua consulta será o seu disco rígido. Os bancos de dados e seus otimizadores de consulta foram projetados para reduzir ao máximo o número de E / Ss do disco. Dado que você tem apenas 3 tabelas, isso será feito com muita confiabilidade.

As velocidades de leitura / gravação de um disco rígido serão 200 a 300 vezes mais lentas que as velocidades de memória. Procure discos rígidos com latência muito rápida e velocidades rápidas de leitura e gravação. Se todos esses dados estiverem em uma unidade de 2 TB, é provável que você espere muito tempo para concluir as consultas. A latência do disco rígido é de ~ 10 a 15 milissegundos, enquanto a latência da memória é inferior a 10 nanossegundos. A latência do disco rígido pode ser 1000-2000x mais lenta que a latência da memória. A movimentação do braço mecânico no disco rígido é a coisa MAIS LENTA do sistema inteiro.

Quanta RAM você tem? 16 GB? Digamos que permite manter 32 registros. Você tem 16000 arquivos. Se você estiver indo para a varredura linear de todos os pontos de dados, poderá facilmente terminar de 5 a 10 segundos em tempo de busca sozinho. Então fator na taxa de transferência 50mb / s? Cerca de 7 horas. Além disso, todos os dados salvos temporariamente deverão ser armazenados no disco rígido para liberar espaço para a leitura de novos dados.

Se você estiver usando um dispositivo de armazenamento compartilhado que está sendo usado ativamente por outros usuários ... sua melhor aposta será executar tudo à noite.

Reduzir o número de consultas aninhadas também ajuda. As consultas aninhadas resultam em tabelas temporárias que debatem ainda mais o seu disco rígido. Espero que você tenha muito espaço livre no seu disco rígido.

A otimização de consulta pode olhar apenas uma consulta por vez. Portanto, instruções de seleção aninhadas não podem ser otimizadas. NO ENTANTO, se você souber que uma consulta aninhada específica resultará em um pequeno conjunto de dados a ser retornado, mantenha-o. A otimização de consulta usa histogramas e suposições aproximadas, se você souber algo sobre os dados e a consulta, vá em frente e faça-o.

Quanto mais você souber sobre como seus dados são armazenados em disco, mais rápido você poderá escrever suas consultas. Se tudo foi armazenado sequencialmente na chave primária, pode ser benéfico classificar as chaves primárias retornadas de uma consulta aninhada. Além disso, se você puder reduzir o conjunto de conjuntos de dados que você precisa analisar antes, faça-o. Dependendo do seu sistema, você pode ver cerca de 1 segundo de transferência de dados por arquivo.

Se você modificar os valores de nome (os varchars), eu o mudaria para um tipo de dados com tamanho máximo, impedirá a fragmentação e o trade-off será apenas mais alguns bytes de memória. Talvez um NVARCHAR com 100 no máximo.

Quanto aos comentários sobre desnormalização da tabela. Eu acho que pode ser melhor apenas armazenar os pontos de dados em grupos maiores (talvez como espectros) e depois fazer a análise dos dados em python ou em uma linguagem que interaja com o banco de dados. A menos que você seja um Assistente para SQL.


3
Você enfatiza a enorme diferença entre a latência do disco rígido e a memória, mas seus números diminuem por um fator de 1000. Se os discos rígidos tiverem uma latência de cerca de 10ms e 10ns de memória, as latências não diferem por um fator de 1.000, mas um fator de 1.000.000!
precisa saber é o seguinte

6

Para mim, parece um cenário de uso em que você deseja algo como um "armazenamento de colunas relacional", conforme descrito aqui .

Talvez eu esteja entendendo mal o design, mas se você estiver lidando principalmente com uma grande coleção de matrizes, armazená-las em tabelas orientadas a linhas típicas significa que cada elemento é semelhante a uma fatia. Se você estiver interessado em analisar fatias de maneira típica, isso faz sentido, mas pode ser menos eficiente se você estiver realmente analisando colunas inteiras de cada vez.

Ao recuperar as matrizes, além de não ser necessário associá-la a outra tabela resultante de sua normalização, é possível recuperar a série como uma matriz e não como um hash.

Eu realmente posso estar entendendo mal o problema e nem estou sugerindo uma solução específica.

Aqui está outra palestra que pode ser relevante, mesmo que não seja realmente uma solução atual ou implantável.


6

Eu recomendo que você tente particionar sua tabela. Temos mais de 80 mil linhas em uma única tabela (dados do mercado de ações) e não temos problemas para acessá-lo rapidamente.

Dependendo de como você pretende pesquisar seus dados, você deve projetar suas partições. No nosso caso, a data funciona bem porque consultamos datas específicas.

http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html

http://www.slideshare.net/datacharmer/mysql-partitions-tutorial


5

Sim mas...

Eu trabalhei com tabelas que tinham 2 bilhões de linhas. No entanto, espera-se que apenas as consultas usando PK sejam rápidas.

Mais importante ainda, o hardware tinha RAM suficiente para caber tabelas inteiras na memória. Quando isso se tornou um problema (máximo de 96 GB na época), optou pelo particionamento vertical, mantendo o tamanho da mesa posta em cada máquina pequeno o suficiente para caber na memória. Além disso, as máquinas foram conectadas via fibra de 10Gb, portanto a taxa de transferência de rede não era um problema.

Entre. seu esquema se parece com algo que poderia se encaixar na solução NoSQL, usando run_idcomo chave de hash para espectros e spectrum_idcomo chave de hash para pontos de dados.


4

Escrevi sobre esse tópico no meu blog: http://www.tocker.ca/2013/10/24/improving-the-performance-of-large-tables-in-MySQL.html

Para repetir alguns dos pontos principais:

  • As árvores B degradam à medida que aumentam e não cabem na memória (o MySQL não está sozinho aqui).
  • O InnoDB possui alguns recursos para ajudar a manter um desempenho (alterar buffer; anteriormente chamado de 'inserir buffer').
  • Particionar também pode ajudar.

Nos comentários do meu post, Tim Callaghan vinculou a este: http://www.tokutek.com/resources/benchmark-results/benchmarks-vs-innodb-hdds/#iiBench

O que mostra a inserção de 1 bilhão de linhas usando o benchmark iibench.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.