Otimização do MariaDB - Databases - Software - Computers

Otimização do MariaDB

Índice

Visão Geral da Otimização
Limitações do Projeto MySQL/Trocas
Portabilidade
Para que Utilizamos o MySQL?
O Pacote de Benchmark do MariaDB
Utilizando seus Próprios Benchmarks
Otimizando SELECTs e Outras Consultas
Sintaxe de EXPLAIN (Obter informações sobre uma SELECT)
Estimando o Desempenho de uma Consulta
Velocidade das Consultas que Utilizam SELECT
Como o MariaDB Otimiza Cláusulas WHERE
Como o MariaDB Otimiza IS NULL
Como o MariaDB Otimiza Cláusulas DISTINCT
Como o MariaDB Otimiza LEFT JOIN e RIGHT JOIN
Como o MariaDB Otimiza Cláusulas ORDER BY
Como o MariaDB Otimiza Cláusulas LIMIT
Performance das Consultas que Utilizam INSERT
Performance das Consultas que Utilizam UPDATE
Performance das Consultas que Utilizam DELETE
Mais Dicas sobre Otimizações
Detalhes sobre Locks
Como o MariaDB Trava as Tabelas
Detalhes sobre Lock de Tabelas
Otimizando a Estrutura de Banco de Dados
Opções do Projeto
Deixando os Dados com o Menor Tamanho Possível
Como o MariaDB Utiliza Índices
Índices de Colunas
Índices de Múltiplas Colunas
Como o MariaDB Conta as Tabelas Abertas
Como o MariaDB Abre e Fecha as Tabelas
Desvantagem em Criar um Número Grande de Tabelas no Mesmo Banco de Dados
Otimizando o Servidor MySQL
Sintonia dos Parâmetros em Tempo de Sistema/Compilação e na Inicialização
Parâmetros de Sintonia do Servidor
Como a Compilação e a Ligação Afetam a Velocidade do MariaDB
Como o MariaDB Utiliza a Memória
Como o MariaDB Utiliza o DNS
Sintaxe de SET
Detalhes de Disco
Utilizando Links Simbólicos

Otimização é uma tarefa complicada porque necessita um entendimento do sistema como um todo. Enquanto for possível fazer algumas otimizações com pequeno conhecimento de seu sistema ou aplicação, quanto mais otimizado você desejar que o seu sistema esteja, mais terá que saber sobre ele.

Este tentará explicar e fornecer alguns exemplos de diferentes formas de otimizar o MariaDB. Lembre-se, no entanto, que sempre existirão (cada vez mais difíceis) formas adicionais de deixar seu sistema mais rápido.

Visão Geral da Otimização

Limitações do Projeto MySQL/Trocas
Portabilidade
Para que Utilizamos o MySQL?
O Pacote de Benchmark do MariaDB
Utilizando seus Próprios Benchmarks

A parte mais importante para obter um sistema rápido é com certeza o projeto básico. Você também precisa saber quais tipos de coisas seus sistema estará fazendo, e quais são gargalos existentes.

Os gargalos mais comuns são:

Limitações do Projeto MySQL/Trocas

Quando usamos o mecanismos de armazenamento MyISAM, o MariaDB utiliza travamento de tabela extremamente rápidos (múltiplas leituras / única escrita). O maior problema com este tipo de tabela ocorre quando você tem uma mistura do fluxo fixo de atualizações e seleções lentas na mesma tabela. Se isto for um problema com algumas tabelas, você pode usa outro tipo de tabela. Leia Tipos de Tabela do MariaDB.

O MariaDB pode trabalhar com tabelas transacionais e não transacionais. Para trabalhar sem problemas com tabelas não transacionais (nas quais não se pode fazer um rollback se alguma coisa der errada), o MariaDB tem as seguintes regras:

Para mais informações sobre isto, veja Leia 'Como o MariaDB Lida com Restrições'.

O mostrado acima quer dizer que não se deve usar o MariaDB para verificar o conteúdo dos campos, mas deve se fazer isto no aplicativo.

Portabilidade

Como todos os servidores SQL implementam diferentes partes de SQL, é trabalhoso escrever aplicativos SQL portáveis. Para selects/inserts muito simples é muito fácil, mas quanto mais recursos você precisa, mais difícil se torna. Se você quiser uma aplicação quue é rápida com muitos bancos de dados ela se torna ainda mais difícil.

Para fazer um aplicativo portável complexo você precisa escolher um número de servidores SQL com o qual ele deve trabalhar.

Você pode utilizar o MariaDB programa/web-page crash-me - - para encontrar funções, tipos e limites que você pode utilizar com uma seleção de servidores de bancos de dados. O Crash-me agora testa quase tudo possível, mas continua compreensível com aproximadamente 450 itens testados.

Por exemplo, você não deve ter nomes de colunas maior do que 18 caracteres se desejar utilizar o Informix ou DB2.

Os programas de benchmarks e crash-me do MariaDB são bastante independentes do bancos de dados. Dando uma olhada em como nós os tratamos, você pode sentir o que é necessário para escrever sua aplicação independente do banco de dados. Os benchmarks podem ser encontrados no diretório sql-bench na distribuição fonte do MariaDB. Eles são escritos em Perl com a interface de banco de dados DBI (que resolve a parte do problema de acesso).

Veja http://www.mysql.com/information/benchmarks.html para os resultados deste benchmark.

Como pode ser visto nestes resultados, todos os bancos de dados tem alguns pontos fracos. Isto é, eles possuem diferentes compromissos de projeto que levam a comportamentos diferentes.

Se você procura por independencia de banco de dados, precisará ter uma boa idéia dos gargalos de cada servidor SQL. O MariaDB é muito rápido para recuperação e atualização de dados, mas terá problemas em misturar leituras/escritas lentas na mesma tabela. O Oracle, por outro lado, possui um grande problema quando você tentar acessar registros que foram recentemente atualizados (até eles serem atualizados no disco). Bancos de dados transacionais geralmente não são muito bons gerando tabelas de resumo das tabelas log, nestes casos o travamento de registros é praticamente inútil.

Para fazer sua aplicação realmente independente de banco de dados, você precisará definir uma interface que possa ser expandida, por meio da qual você fará a manipulação dos dados. Como o C++ está disponível na maioria dos sistemas, faz sentido utilizar classes C++ para fazer a interface ao banco de dados.

Se você utilizar algum recurso específico para algum banco de dados (como o comando REPLACE no MySQL), você deve codificar um método para os outros serviodores SQL para implementar o mesmo recurso (mas mais lento). Com o MariaDB você pode utilizar a sintaxe /*! */ para adicionar palavras chave específicas do MariaDB para uma query. O código dentro de /**/ será tratado como um comentário (ignorado) pela maioria dos servidores SQL.

Se alta performance REAL é mais importante que exatidão, como em algumas aplicações WEB, uma possibilidade é criar uma camada de aplicação que armazena todos os resultados para lhe fornecer uma performance ainda mais alta. Deixando resultados antigos 'expirar' depois de um tempo, você pode manter o cache razoavelmente atual. Isto é muito bom no caso de uma carga extremamente pesada, pois neste caso você pode aumentar o cache dinamicamente e configurar o tempo de expiração maior até que as coisas voltem ao normal.

Neste caso a informação de criação de tabelas devem conter informações do tamanho inicial do cache e com qual frequência a tabela, normalmente, deve ser renovada.

Para que Utilizamos o MySQL?

Durante o desenvolvimento inicial do MariaDB, os recursos do MariaDB foram desenvolvidos para atender nosso maior cliente. Eles lidam com data warehousing para alguns dos maiores varejistas na Suécia.

De todas as lojas, obtemos resumos semanais de todas as transações de cartões de bonus e esperamos fornecer informações úteis para ajudar os donos das lojas a descobrir como suas campanhas publicitárias estão afetando seus clientes.

Os dados são bem grandes (cerca de 7 milhões de transações por mês), e armazenamos dados por cerca de 4-10 anos que precisamos apresentar para os usuários. Recebemos requisições semanais dos clientes que desejam ter acesso 'instantâneo' aos novos relatórios contendo estes dados.

Resolvemos este problema armazenando todas informações mensalmente em tabelas com transações compactadas. Temos um conjunto de macros (script) que geram tabelas resumidas agrupadas por diferentes critérios (grupo de produto, id do cliente, loja...) das tabelas com transações. Os relatórios são páginas Web que são geradas dinamicamente por um pequeno shell script que analisa uma página Web, executa as instruções SQL na mesma e insere os resultados. Nós usariamos PHP ou mod_perl mas eles não estavam disponíveis na época.

Para dados graficos escrevemos um ferramenta simples em C que pode produzir GIFs baseados no resultado de uma consulta SQL (com alguns processamentos do resultado). Isto também é executado dinamicamente a partir do script Perl que analisa os arquivos HTML.

Na maioria dos casos um novo relatório pode simplesmente ser feito copiando um script existente e modificando a consulta SQL no mesmo. Em alguns casos, precisamos adicionar mais campos a uma tabela de resumo existente ou gerar uma nova, mas isto também é bem simples, pois mantemos todas as tabelas com as transaçõs no disco. (Atualmente possuimos pelo menos 50G de tabelas com transações e 200G de outos dados do cliente.)

Nós também deixamos nossos clientes acessarem as tabelas sumárias diretamente com ODBC para que os usuários avançados possam também fazer experimentar com os dados.

Nós não tivemos nenhum problema lidando com isso em um servidor Sun Ultra SPARCstation (2x200 Mhz) bem modesto. Atualmente atualizamos um de nossos servidores para um UltraSPARC com 2 CPUs de 400 Mhz, e planejamos lidar com transações no nível de produto, o que pode significar um aumento de pelo menos dez vezes nosso volume de dados. Acreditamos que podemos lidar com isto apenas adicionando mais disco aos nossos sistemas.

Também estamos experimentando com Intel-Linux para obter mais poder de CPU por um melhor preço. Agora que possuimos o formato binários do bancos de dados portáveis (a partir da versão 3.23), começaremos a utilizá-lo para partes da aplicação.

Nossa sensação inicial é que o Linux irá atuar muito melhor em cargas baixas e médias e o Solaris irá atuar melhor quando você começar a ter uma carga alta pelo uso extremo de IO de disco, mas ainda não temos nada conclusivo sobre isto. Depois de algumas discussões com um desenvolvedor do kernel do Linux, concluímos que isto pode ser um efeito colateral do Linux; alocar muitos recursos para uma tarefa batch que a performance interativa se torna muito baixa. Isto deixa a máquina muito lenta e sem resposta enquanto grandes batches estiverem em execução. Esperamos que isto tenha um tratamento melhor em futuras versões do kernel Linux.

O Pacote de Benchmark do MariaDB

Esta seção deve conter uma descrição técnica do pacote de benchmarks do MariaDB (e crash-me), mas a descrição ainda não está pronta. Atualmente, você pode ter uma boa idéia do benchmark verificando os códigos e resultados no diretório sql-bench em qualquer distribuição fonte do MariaDB.

Este conjunto de benchmark pretende ser um benchmark que irá dizer a qualquer usuário que operações uma determinada implementação SQL irá realizar bem ou mal.

Note que este benchmark utiliza uma única thead, portanto ele mede o tempo mínimo para as operações realizadas. Planejamos adicionar vários testes multi-threaded no conjunto de benchmark no futuro.

A seguinte tabela mostra alguns resultados comparativos de benchmark para diversos servidores de bancos de dados quando acessados por meio do ODBC em uma máquina Windows NT 4.0.

Lendo 2000000 linhas por índice Segundos Segundos
mysql 367 249
mysql_odbc 464
db2_odbc 1206
informix_odbc 121126
ms-sql_odbc 1634
oracle_odbc 20800
solid_odbc 877
sybase_odbc 17614
Inserindo 350768 linhas Segundos Segundos
mysql 381 206
mysql_odbc 619
db2_odbc 3460
informix_odbc 2692
ms-sql_odbc 4012
oracle_odbc 11291
solid_odbc 1801
sybase_odbc 4802

Para os testes anteriores, o MariaDB foi executado com um cache de índices de 8M.

Temos concentrado alguns resultados de benchmarks em http://www.mysql.com/information/benchmarks.html.

Perceba que a Oracle não está incluída porque eles solicitaram a remoção. Todos benchmarks Oracle devem ser aprovados pela Oracle! Acreditamos que os benchmarks da Oracle são MUITO tendecioso pois os benchmarks acima devem ser executados supostamente para uma instalação padrão para um único cliente.

Para executar a suite de benchmarks, as seguintes exigências devem ser satisfeitas:

O pacote de benchmark está localizado no diretório sql-bench da distribição fonte do MariaDB. Para executar o teste de benchmark, altera a localização dentro daquele diretório e execute o script run-all-tests:

shell> cd sql-bench
shell> perl run-all-tests --server=server_name

server_name é um dos servidores suportados. Você pode obter uma lista de todos parâmetros e servidores suportados executando run-all-tests --help.

crash-me tenta determinar quais recursos um banco de dados suporta e quais suas capacidades e limitações atuais para a execução de consultas. Por exemplo, ele determina:

Podemos encontrar o resultado do crash-me para diversos bancos de dados em http://www.mysql.com/information/crash-me.php.

Utilizando seus Próprios Benchmarks

Definitivamente você deve fazer benchmarks de sua aplicação e banco de dados para saber quais são os gargalos. Corrigindo (ou substituindo o gargalho com um módulo burro) você pode facilmente identificar o próximo gargalo (e continuar). Mesmo se a performance geral para sua aplicação atualmente é aceitável, você deve pelo menos criar um plano para cada gargalo e decidir como resolvê-lo se algum dia você precisar de performance extra.

Para um exemplo de programas de benchmarks portáveis, consulte o conjunto de benchmarks do MariaDB. Leia 'O Pacote de Benchmark do MariaDB'. Você pode pegar qualquer programa deste conjunto e modificá-lo para suas necessidades. Fazendo isto você pode tentar soluções diferentes para seu problema e testar qual é a mais rápida para você.

Outro pacote de benchmark grátis é o Open Source Database Benchmark disponível em http://osdb.sourceforge.net/.

É muito comum que um problemas ocorram apenas quando o sistema estiver muito carregado. Nós tivemos alguns clientes que nos contactaram quando eles testaram um sistema em produção e encontraram problemas de carga. Na maioria dos casos, problemas de desempenho ocorrem devido a assuntos relacionados ao projeto básico do banco de dados (busca em tabelas não são bons com alta carga) ou problemas com o sistema operacional e de bibliotecaa. A maioria das vezes, estes problemas seriam MUITO mais fáceis de resolver se os sistemas já não estivessem em uso.

Para evitar problemas deste tipo, você deve colocar algum esforço em testar a performance de toda sua aplicação sobre a pior carga possível! Você pode utilizar o Super Smack para isto. Ele está disponível em: http://www.mysql.com/Downloads/super-smack/super-smack-1.0.tar.gz. Como o nome sugere, ele pode derrubar seu sistema se você solicitar, portanto, utilize-o somente em sistemas de desenvolvimento.

Otimizando SELECTs e Outras Consultas

Sintaxe de EXPLAIN (Obter informações sobre uma SELECT)
Estimando o Desempenho de uma Consulta
Velocidade das Consultas que Utilizam SELECT
Como o MariaDB Otimiza Cláusulas WHERE
Como o MariaDB Otimiza IS NULL
Como o MariaDB Otimiza Cláusulas DISTINCT
Como o MariaDB Otimiza LEFT JOIN e RIGHT JOIN
Como o MariaDB Otimiza Cláusulas ORDER BY
Como o MariaDB Otimiza Cláusulas LIMIT
Performance das Consultas que Utilizam INSERT
Performance das Consultas que Utilizam UPDATE
Performance das Consultas que Utilizam DELETE
Mais Dicas sobre Otimizações

Primeiramente, uma coisa que afeta todas as consultas: Quanto mais complexo seu sistema de permissões, maior a sobrecarga.

Se você não tiver nenhuma instrução GRANT realizada, MariaDB otmizará a verificação de permissões de alguma forma. Dessa forma, se você possui um volume muito alto, o tempo pode piorar tentando permitir o acesso. Por outro lado, maior verificação de permissões resulta em uma sobrecarga maior.

Se o seu problema é com alguma função explícita do MariaDB, você pode sempre consultar o tempo da mesma com o cliente MySQL:

mysql> SELECT BENCHMARK(1000000,1+1);
+------------------------+
| BENCHMARK(1000000,1+1) |
+------------------------+
| 0 |
+------------------------+
1 row in set (0.32 sec)

O exemplo acima demonstra que o MariaDB pode excutar 1.000.000 expressões + em 0.32 segundos em um PentiumII 400MHz.

Todas funções MariaDB devem ser bem otimizadas, mas existem algumas excessões e o benchmark(loop_count,expression) é uma ótima ferramenta para saber se existe um problema com sua query.

Sintaxe de EXPLAIN (Obter informações sobre uma SELECT)

 EXPLAIN nome_tabela ou EXPLAIN SELECT opções_select

EXPLAIN nome_tabela é um sinônimo para DESCRIBE nome_tabela ou SHOW COLUMNS FROM nome_tabela.

Quando uma instrução SELECT for precedida da palavra chave EXPLAIN, o MariaDB explicará como ele deve processar a SELECT, fornecendo informação sobre como as tabelas estão sendo unidas e em qual ordem.

Com a ajuda de EXPLAIN, você pode ver quando devem ser adicionados índices à tabelas para obter uma SELECT mais rápida que utiliza índices para encontrar os registros.

Voce deve executar frequentemente ANALYZE TABLE para atualizar estatísticas de tabela tais como a cardinalidade das chaves que podem afetar a escolha que o otimizador faz. Leia 'Sintaxe de ANALYZE TABLE'.

Você também pode ver se o otimizador une as tabelas em uma melhor ordem. Para forçar o otimizador a utilizar uma ordem específica de join para uma instrução SELECT, adicione uma cláusula STRAIGHT_JOIN.

Para ligações mais complexas, EXPLAIN retorna uma linha de informação para cada tabela utilizada na instrução SELECT. As tabelas são listadas na ordem que seriam lidas. O MariaDB soluciona todas as joins utilizando um método multi-join de varedura simples. Isto significa que o MariaDB lê uma linha da primeira tabela, depois encontra uma linha que combina na segunda tabela, depois na terceira tabela e continua. Quando todas tabelas são processadas, ele exibe as colunas selecionadas e recua através da lista de tabelas até uma tabela na qual existem registros coincidentes for encontrada. O próximo registro é lido desta tabela e o processo continua com a próxima tabela.

No MariaDB versão 4.1 a saída do EXPLAIN foi alterada para funcionar melhor com construções como UNIONs, subqueries e tabelas derivadas. A mais notável é a adição de duas novas colunas: id e select_type.

A saída de EXPLAIN inclui as seguintes colunas:

Você pode ter uma boa indicação de quão boa é sua join multiplicando todos os valores na coluna rows na saída de EXPLAIN. Isto deve dizer a grosso modo quantos registros o MariaDB deve examinar para executar a consulta. Este número é também usado quando você restringe consultas com a variável max_join_size. Leia 'Parâmetros de Sintonia do Servidor'.

O exemplo a seguir mostra como um JOIN pode ser otimizado progressivamente utilizando a informação fornecida por EXPLAIN.

Suponha que você tem a instrução SELECT exibida abaixo, que você está examinando utilizando EXPLAIN:

EXPLAIN SELECT tt.TicketNumber, tt.TimeIn,
 tt.ProjectReference, tt.EstimatedShipDate,
 tt.ActualShipDate, tt.ClientID,
 tt.ServiceCodes, tt.RepetitiveID,
 tt.CurrentProcess, tt.CurrentDPPerson,
 tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
 et_1.COUNTRY, do.CUSTNAME
 FROM tt, et, et AS et_1, do
 WHERE tt.SubmitTime IS NULL
 AND tt.ActualPC = et.EMPLOYID
 AND tt.AssignedPC = et_1.EMPLOYID
 AND tt.ClientID = do.CUSTNMBR;

Para este exemplo, assuma que:

Initially, before any optimizations have been performed, the EXPLAIN statement produces the following information:

table type possible_keys key key_len ref rows Extra et ALL PRIMARY NULL NULL NULL 74
do ALL PRIMARY NULL NULL NULL 2135
et_1 ALL PRIMARY NULL NULL NULL 74
tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872
 range checked for each record (key map: 35)

Como o tipo é ALL em todas tabelas, esta saída indica que o MariaDB está gerando um produto Cartesiano de todas as tabelas! Isto levará muito tempo para ser executado, pois o produto do número de registros em cada tabela deve ser examinado ! Neste caso, existem * 2135 * 74 * 3872 registros. Se as tabelas forem maiores, imagine quanto tempo este tipo de consulta pode demorar.

Um dos problemas aqui é que o MariaDB não pode (ainda) utilizar índices em colunas de maneira eficiente se elas foram declaras ide forma diferente. Neste contexto, VARCHAR e CHAR são o mesmo a menos que tenham sido declarados com tamanhos diferentes. Como tt.ActualPC é declarado como CHAR(10) e et.EMPLOYID é declarado como CHAR(15), existe aqui uma diferença de tamanho.

Para corrigir esta diferença entre tamanhos de registros, utilize ALTER TABLE para alterar o tamanho de ActualPC de 10 para 15 caracteres:

mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);

Agora ambos campos tt.ActualPC e et.EMPLOYID são VARCHAR(15). Executando a instrução EXPLAIN novamente produzirá este resultado:

table type possible_keys key key_len ref rows Extra tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 Using where do ALL PRIMARY NULL NULL NULL 2135
 range checked for each record (key map: 1)
et_1 ALL PRIMARY NULL NULL NULL 74
 range checked for each record (key map: 1)
et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1

Isto não está perfeito, mas está bem melhor ( o produto dos valores de rows agora menor por um fator de 74 ). Esta versão é executada em vários segundos.

Uma segunda alteração pode ser feita para eliminar as diferenças de tamanho das colunas para as comparações tt.AssignedPC = et_1.EMPLOYID e tt.ClientID = do.CUSTNMBR :

mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15),
 -> MODIFY ClientID VARCHAR(15);

Agora EXPLAIN produz a saída mostrada abaixo:

table type possible_keys key key_len ref rows Extra et ALL PRIMARY NULL NULL NULL 74
tt ref AssignedPC, ActualPC 15 et.EMPLOYID 52 Using where
 ClientID,
 ActualPC et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1
do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1

Este resultado é quase o melhor que se pode obter.

O problema restante é que, por padrão, o MariaDB assume que valores na coluna tt.ActualPC estão distribuídos igualmente, e este não é o caso para a tabela tt. Felizmente, é fácil informar ao MariaDB sobre isto:

shell> myisamchk --analyze PATH_TO_MYSQL_DATABASE/tt
shell> mysqladmin refresh

Agora a join está perfeita, e EXPLAIN produz esta saída:

table type possible_keys key key_len ref rows Extra tt ALL AssignedPC NULL NULL NULL 3872 Using where
 ClientID,
 ActualPC et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1
et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1
do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1

Perceba que a coluna rows na saída de EXPLAIN é uma boa ajuda para otimizador de joins do MariaDB. Para otimizar uma consulta, você deve conferir se os números estão perto da realidade. Se não, você pode obter melhor desempenho utilizando STRAIGHT_JOIN em sua instrução SELECT e tentar listar as tabelas em uma ordem diferente na cláusula FROM.

Estimando o Desempenho de uma Consulta

Na maioria dos casos você pode estimar a performance contando buscas em disco. Para tabelas pequenas, normalmente você pode encontrar o registro com 1 pesquisa em disco (uma vez que o índice provavelmente está no cache). Par tabelas maiores, você pode estimar (usando indíces de arvores B++) que você precisará de: log(row_count) / log(index_block_length / 3 * 2 / (index_length + data_pointer_length)) + 1 buscas em disco para encontrar um registro.

No MariaDB um bloco de índice tem geralmente 1024 bytes e o ponteiro de dados 4 bytes. Uma tabela de 500.000 registros com um índice com tamanho de 3 (inteiro médio) lhe dá: log(500,000)/log(1024/3*2/(3+4)) + 1 = 4 pesquisas.

Como o índice acima necessita cerca de 500,000 * 7 * 3/2 = 5.2M, (assumindo que os buffers de índices são carregados até 2/3, que é o normal) você provavelmente terá grande parte dos índices em memória e provavelmente precisará somente de 1 ou 2 chamadas para ler dados do SO para encontrar o registro.

Entretanto, para escritas, você precisará utilizar 4 requisições para encontrar onde posicionar o novo índice e normalmente 2 buscas para atualizar o índice e escrever o registro.

Perceba que o que foi dito acima não significa que sua aplicação perderá performance por N log N! Como tudo é armazenado no cache de seu SO ou do servidor SQL as coisas começarão a ficar um pouco mais lentas quando as tabelas começarem a crescer. Quando os dados se tornam muito grandes para o cache, as coisas começarão a ficar bem mais lentas até que suas aplicações estejam limitadas a buscas em disco (o que aumenta em N log N). Para evitar isto, aumente o cache de índice quando os dados crescerem. Leia 'Parâmetros de Sintonia do Servidor'.

Velocidade das Consultas que Utilizam SELECT

Em geral, quando você desejar tornar uma consulta lenta SELECT ... WHERE mais rápida, a primeira coisa que deve ser conferida é se você pode ou não adicionar um índice. Leia 'Como o MariaDB Utiliza Índices'. Todas as referências entre diferentes tabelas devem ser feitas normalmente com índices. Você pode utilizar o comando EXPLAIN para determinas quais índices são usados para uma SELECT. Leia 'Sintaxe de EXPLAIN (Obter informações sobre uma SELECT)'.

Algumas dicas gerais:

Como o MariaDB Otimiza Cláusulas WHERE

As otimizações WHERE são colocadas aqui na parte da SELECT porque normalmente elas são usadas com SELECT, mas as mesmas otimizações aplicam-se para WHERE em instruções DELETE e UPDATE.

Note também que esta seção está incompleta. O MariaDB faz várias otimizações e ainda não tivemos tempo para documentarmos todas elas.

Algumas das otimizações feitas pelo MariaDB são são listadas abaixo:

Some examples of queries that are very fast:

mysql> SELECT COUNT(*) FROM tbl_name;
mysql> SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;
mysql> SELECT MAX(key_part2) FROM tbl_name
 -> WHERE key_part_1=constant;
mysql> SELECT ... FROM tbl_name
 -> ORDER BY key_part1,key_part2,... LIMIT 10;
mysql> SELECT ... FROM tbl_name
 -> ORDER BY key_part1 DESC,key_part2 DESC,... LIMIT 10;

As seguintes consultas são resolvidas utilizando somente a árvore de índices (assumindo que as colunas indexadas são numéricas):

mysql> SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val;
mysql> SELECT COUNT(*) FROM tbl_name
 -> WHERE key_part1=val1 AND key_part2=val2;
mysql> SELECT key_part2 FROM tbl_name GROUP BY key_part1;

As consultas a seguir utilizam indexação para recuperar os registros na ordem de classificação sem um passo de ordenação separado:

mysql> SELECT ... FROM tbl_name
 -> ORDER BY key_part1,key_part2,... ;
mysql> SELECT ... FROM tbl_name
 -> ORDER BY key_part1 DESC,key_part2 DESC,... ;

Como o MariaDB Otimiza IS NULL

O MariaDB pode fazer a mesma otimização em column IS NULL que ele pode com column = constant_value. Por exemplos, o MariaDB pode usar índices e faixas para buscar por NULL com IS NULL.

SELECT * FROM table_name WHERE key_col IS NULL;
SELECT * FROM table_name WHERE key_col <=> NULL;
SELECT * FROM table_name WHERE key_col=# OR key_col=# OR key_col IS NULL

Se você usa column_name IS NULL em um NOT NULL em uma cláusula WHERE na tabela que não é usada no OUTER JOIN, esta espressão será otimizada de qualquer forma.

O MariaDB 4.1. pode adicionalmente otimizar a combinação column = expr AND column IS NULL, uma forma que é comum em sub queries resolvidas. EXPLAIN mostrará ref_or_null quando esta otimização é usada.

Esta otimização pode tratar um IS NULL para qualquer parte da chave.

Alguns exemplos de consultas que são otimizadas (assumindo chave em t2 (a,b)):

SELECT * FROM t1 WHERE t1.a=expr OR t1.a IS NULL;
SELECT * FROM t1,t2 WHERE t1.a=t2.a OR t2.a IS NULL;
SELECT * FROM t1,t2 WHERE (t1.a=t2.a OR t2.a IS NULL) AND t2.b=t1.b;
SELECT * FROM t1,t2 WHERE t1.a=t2.a AND (t2.b=t1.b OR t2.b IS NULL);
SELECT * FROM t1,t2 WHERE (t1.a=t2.a AND t2.a IS NULL AND ...) OR (t1.a=t2.a AND t2.a IS NULL AND ...);

ref_or_null funciona fazendo primeiro uma leitura na chave indicada e depois disto uma busca separada por linhas com chave NULL.

Note que a otimização só pode tratar um nível IS NULL.

SELECT * FROM t1,t2 where (t1.a=t2.a AND t2.a IS NULL) OR (t1.b=t2.b AND t2.b IS NULL);

No caso acima o MariaDB só usará busca de chave na parte (t1.a=t2.a AND t2.a IS NULL) e não poderá usar a parte da chave em b.

Como o MariaDB Otimiza Cláusulas DISTINCT

DISTINCT combinado com ORDER BY também irá em vários casos criar uma tabela temporária.

Note que como DISTINCT pode usar GROUP BY, você deve estar ciente de como o MariaDB funciona com campos na parte ORDER BY ou HAVING que não são parte dos campos selecionados. Leia 'GROUP BY com Campos Escondidos'.

Quando combinando LIMIT row_count com DISTINCT, o MariaDB irá parar logo que encontrar row_count registros únicos.

Se você não utiliza colunas de todas tabelas usadas, o MariaDB irá parar a varredura das tabelas não usadas logo que encontrar a primeira coincidência.

SELECT DISTINCT t1.a FROM t1,t2 where t1.a=t2.a;

Neste caso, assumindo que t1 é usando antes de t2 (confira com EXPLAIN), MariaDB irá parar de ler de t2 (para aquele registro particular em t1) quandoo primeiro registro em t2 for encontrado.

Como o MariaDB Otimiza LEFT JOIN e RIGHT JOIN

A LEFT JOIN B join_condition no MariaDB está implementada como a seguir:

RIGHT JOIN é implementado de forma análoga à LEFT JOIN.

A ordem de leitura das tabelas forçada por LEFT JOIN e STRAIGHT JOIN irá ajudar o otimizador de joins (que calcula em qual ordem as tabelas devem ser unidas) a fazer seu trabalho mais rapidamente, já que haverão poucas permutações de tabelas a serem conferidas.

Perceba que o texto acima significa que se você fizer uma consulta do tipo:

SELECT * FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key)
 WHERE b.key=d.key

A partir do MariaDB 4.0.14, o MariaDB faz a seguinte otimização LEFT JOIN:

Se a condição WHERE é sempre falsa para a linha NULL gerada, o LEFT JOIN é alterado para um join normal.

Por exemplo, na seguinte consulta a cláusula WHERE seria falso se t2.coluna fosse NULL, asssim é seguro converter para uma join normal.

SELECT * FROM t1 LEFT t2 ON (column) WHERE t2.column2 =5;
->
SELECT * FROM t1,t2 WHERE t2.column2=5 AND t1.column=t2.column;

Isto pode ser feito mais rápido já que o MariaDB pode agora usar a tabela t2 antes da tabela t1 se resultasse consulta melhor. Para forçar uma ordem de tabela específica, use STRAIGHT JOIN.

O MariaDB irá fazer uma pesquisa completa em b já que o LEFT JOIN irá força-lo a ser lido antes de d.

A correção neste caso é alterar a consulta para:

SELECT * FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key)
 WHERE b.key=d.key

Como o MariaDB Otimiza Cláusulas ORDER BY

Em alguns casos o MariaDB pode utilizar índices para satisfazer uma requisição de ORDER BY ou GROUP BY sem fazer uma ordenação extra.

O índice também pode ser usado mesmo se o ORDER BY não coincidir exatamente com o índice, uma vez que todas as partes de índices não usadas e todos os extras na coluna ORDER BY são constantes na cláusula WHERE. A seguinte consulta usará o índice para resolver a parte ORDER BY / GROUP BY:

SELECT * FROM t1 ORDER BY key_part1,key_part2,...
SELECT * FROM t1 WHERE key_part1=constante ORDER BY key_part2
SELECT * FROM t1 WHERE key_part1=constante GROUP BY key_part2
SELECT * FROM t1 ORDER BY key_part1 DESC,key_part2 DESC SELECT * FROM t1 WHERE key_part1=1 ORDER BY key_part1 DESC,key_part2 DESC

Alguns casos onde o MariaDB não pode usar índices para resolver o ORDER BY: (Note que o MariaDB ainda usará índices para encontrar o registro que coincide com a cláusula WHERE):

Nestes casos onde o MariaDB tem que ordenar o resultado, ele usa o seguinte algoritmo:

Você pode verificar com EXPLAIN SELECT ... ORDER BY se o MariaDB pode usar índices para resolver a consulta. Se você obtiver Using filesort na coluna extra, então o MariaDB não pode usar índices para resolver o ORDER BY. Leia 'Sintaxe de EXPLAIN (Obter informações sobre uma SELECT)'.

Se você quiser ter uma velocidade ORDER BY maior, primeiro você deve ver se você pode fazer que o MariaDB use índices em vez de fazer um fase de ordenação extra. Se não for possível, então você pode fazer:

Por padrão, o MariaDB ordena todas as consultas GROUP BY x,y[,...] como se você tivesse especificado ORDER BY x,y[,...]. Se você incluir a cláusula ORDER BY explicitamente, o MariaDB a otimizará sem qualquer penalidade na velocidade, embora a ordenacao ainda ocorra. Se a consulta inclui um GROUP BY mas você deseja evitar a sobrecarga da ordenar o resultado, você pode suprimir a ordenacao especificando ORDER BY NULL:

INSERT INTO foo SELECT a,COUNT(*) FROM bar GROUP BY a ORDER BY NULL;

Como o MariaDB Otimiza Cláusulas LIMIT

Em alguns casos o MariaDB irá tratar a consulta de maneira diferente quando você estiver utilizando LIMIT row_count e não estiver utilizando HAVING:

Performance das Consultas que Utilizam INSERT

O tempo para inserir um registro consiste aproximadamente de:

onde os números são de certa forma proporcionais ao tempo total. Isto não leva em consideracão o sobrecarga inicial para abrir tabelas (que é feita uma vez para cada consulta concorrente em execução).

O tamanho da tabela diminuem a velocidade da inserção de índices em N log N (Arvores B).

Algumas maneiras de acelerar as inserções:

Para obter mais velocidade para LOAD DATA INFILE e INSERT, aumente o tamanho do buffer de chaves. Leia 'Parâmetros de Sintonia do Servidor'.

Performance das Consultas que Utilizam UPDATE

Consultas de atualização são otimizadas como uma consulta que usa SELECT com a sobrecarga adicional de escrita. A velocida da escrita depende do tamanho dos dados e do número de índices que serão atualizados. Índices que não forem alterados não serão atualizados.

Outra forma para obter atualizações rápidas é atrasar as atualizações e então fazer várias atualizações em um registro posteriormente. Fazer várias atualizações em um registro é muito mais rápido do que fazer uma por vez se você travar a tabela.

Perceba que, com formato de registros dinâmicos, atualizar um registro para um valor maior que o tamanho total pode dividir o registro. Portanto, se você faz isso frequentemente, é muito importante usar OPTIMZE TABLE de vez em quando. Leia 'Sintaxe de OPTIMIZE TABLE'.

Performance das Consultas que Utilizam DELETE

Se você deseja apagar todos os registros em uma tabela, deve usar TRUNCATE TABLE nome_tabela. Leia 'Sintaxe TRUNCATE'.

O tempo para apagar um registro é exatamente proporcional ao número de índices. Para apagar registros mais rapidamente, você pode aumentar o tamanho do cache de índices. Leia 'Parâmetros de Sintonia do Servidor'.

Mais Dicas sobre Otimizações

Dicas não ordenadas para sistemas rápidos:

Detalhes sobre Locks

Como o MariaDB Trava as Tabelas
Detalhes sobre Lock de Tabelas

Como o MariaDB Trava as Tabelas

Você pode encontrar uma discussão sobre diferentes métodos de bloqueios no apêndice. Leia Seção E.4, 'Métodos de Lock'.

Todos os bloqueios no MariaDB são livres de deadlock, exceto para tipos de tabela InnoDB e BDB. Isto é gerenciado sempre requisitando todos os bloqueios necessários de uma vez no começo de uma consulta e sempre bloqueando as tabelas na mesma ordem.

Tipos de tabela InnoDB automaticamente adquire seus locks de registro e os tipos de tabela BDB seus locks de páginas, durante o processamento das instruções SQL, e não no início da transação.

O método de bloqueio que o MariaDB utiliza para ESCRITA funciona da seguinte forma:

O método de bloqueio que o MariaDB utilizado para LEITURA funciona da seguinte maneira:

Quando um bloqueio é liberado, a trava fica disponível para as threads na fila de bloqueios de escrita, e então para as threads na fila de bloqueios de leitura.

Isto significa que se você possui várias atualizações em uma tabela, instruções SELECT irão esperar até que não existam mais atualizações.

Para contornar este problema no caso onde você precisa fazer várias operações de INSERT e SELECT em uma tabela, você pode inserir registros em uma tabela temporária e atualizar a tabela real com os registros da tabela temporária de uma só vez.

Isto pode ser feito usando o código a seguir:

mysql> LOCK TABLES real_table WRITE, insert_table WRITE;
mysql> INSERT INTO real_table SELECT * FROM insert_table;
mysql> TRUNCATE TABLE insert_table;
mysql> UNLOCK TABLES;

Você pode utilizar as opções LOW_PRIORITY com INSERT, UPDATE ou DELETE ou HIGH_PRIORITY com SELECT se você desejar priorizar a recuperação em alguns casos específicos. Também podei-se iniciar o mysqld com --low-priority-updates para obter o mesmo comportamento.

Utilizar SQL_BUFFER_RESULT pode também tornar a criação de locks de tabelas mais curtos.See 'Sintaxe SELECT'.

Você também pode alterar o código de bloqueioss no mysys/thr_lock.c para usar uma fila simples. Neste caso, bloqueios de escrita e leitura devem ter a mesma prioridade, o que pode ajudar em algumas aplicações.

Detalhes sobre Lock de Tabelas

O código de bloqueio de tabelas no MariaDB é livre de deadlock.

O MariaDB utiliza bloqueio de tabelas (no lugar de bloqueio de registros ou colnas) em todos os tipos de tabelas, exceto tabelas BDB, para obter uma alta velocidade nos bloqueios. Para grandes tabelas, bloqueio de tabelas é MUITO melhor que bloqueio de registros para a maioria das aplicações, mas existem, é claro, algumas desvantagens.

Para tabelas BDB e InnoDB, O MariaDB só utiliza bloqueio de tabelas se você bloquear explicitamente a tabela com LOCK TABLES ou executar um comando quer irá modificar todos os registros na tabela, como ALTER TABLE. Para estes tipos de tabelas nós recomendamos a você não utilizar LOCK TABLES.

No MariaDB versão 3.23.7 ou superior , você pode inserir registros em tabelas MyISAM ao mesmo tempo que outras threads estão lendo da mesma tabela. Perceba que atualmente isto funciona somente se não existirem buracos depois de registros apagados na tabela no momento que a inserção é feita. Quando todos os buracos forem preenchidos com novos dados, inserções concorrentes irão automaticamente ser habilitadas novamente.

O bloqueio de tabelas habilita várias threads para lerem de uma tabela ao mesmo tempo, mas se uma thread desejar escrever a uma tabela, ela primeiramente deve obter acesso exclusivo. Durante a atualização, todas outras threads que desejarem acessar esta tabela em particular irão esperar até que a atualização acabe.

Como atualizações em tabelas normalmente são consideradas mais importantes que SELECT, todas as instruções que atualizam uma tabela tem maior prioridade que instruções que simplesmente recuperam informações. Isto deve garantir que atualizações não fiquem na fila por terem sido passadas várias consultas pesadas em uma tabela específica. (Você pode alterar isto utilizando LOW_PRIORITY com a instrução que faz a atualização ou HIGH_PRIORITY com a instrução SELECT.)

A partir do MariaDB versão 3.23.7 pode-se utilizadar a variável max_write_lock_count para forçar o MariaDB a fornecer temporariamente a todas as instruções SELECT, que esperam por uma tabela, uma prioridade mais alta depois de um número específico de inserções em uma tabela.

O bloqueio de tabela não é, no entanto, muito bom sobre os seguintes cenários:

Algumas soluções possíveis para este problema são:

Otimizando a Estrutura de Banco de Dados

Opções do Projeto
Deixando os Dados com o Menor Tamanho Possível
Como o MariaDB Utiliza Índices
Índices de Colunas
Índices de Múltiplas Colunas
Como o MariaDB Conta as Tabelas Abertas
Como o MariaDB Abre e Fecha as Tabelas
Desvantagem em Criar um Número Grande de Tabelas no Mesmo Banco de Dados

Opções do Projeto

O MariaDB mantem dados de registros e índices em arquivos separados. Vários (quase todos) bancos de dados misturam dados de registros e índice no mesmo arquivo. Nós acreditamos que a escolha do MariaDB é melhor para uma ampla escala de sistemas modernos.

Outra forma de armazenar os dados de registros é manter a informação para cada coluna em uma área separada (exemplos são o SDBM e o Focus). Isto irá causar um ponto de performance para toda consulta que acessar mais de uma coluna. Como isto degrada rapidamente quando mais de uma coluna é acessada, acreditamos que este modelo não é bom para propósitos gerais de bancos de dados.

O caso mais comum é aquele em que o índice e dados são armazenados juntos (como no Oracle/Sybase). Neste caso você irá encontrar a informação do registro na folha da página de índice. A coisa boa com este layout é que ele, em vários casos, dependendo de como o índice é armazenado no cache, salva uma leitura de disco. As desvantagens deste layout são:

Deixando os Dados com o Menor Tamanho Possível

Uma das otimizações mais básicas é tentar manter seus dados (e índices) utilizando o menor espaço possível no disco (e em memória). Isto pode fornecer grandes melhorias porque a leitura de disco é mais rápida e normalmente menos memória principal será usada. A indexação também exige menos recursos se for feita em colunas menores.

O MariaDB suporta vários diferentes tipos de tabelas e formatos de registros. Você pode ter um ótimo ganho de performance escolhendo o formato certo de tabela a ser usada. Leia Tipos de Tabela do MariaDB.

Pode-se obter melhor performance em uma tabela e minimizar espaço de armazenagem utilizando as técnicas listadas abaixo:

Como o MariaDB Utiliza Índices

Os índices são utilizados para encontrar registros com um valor específico de uma coluna rapidamente. Sem um índice o MariaDB tem de iniciar com o primeiro registro e depois ler através de toda a tabela até que ele encontre os registros relevantes. Quanto maior a tabela, maior será o custo. Se a tabela possui um índice para as colunas em questão, o MariaDB pode rapidamente obter uma posição para procurar no meio do arquivo de dados sem ter que varrer todos os registros. Se uma tabela possui 1000 registros, isto é pelo menos 100 vezes mais rápido do que ler todos os registros sequencialmente. Note que se você precisar acessar quase todos os 1000 registros, seria mais rápido acessá-los sequencialmente porque evitaria acessos ao disco.

Todos os índices do MariaDB (PRIMARY, UNIQUE e INDEX) são armazenados em árvores B. Strings são automaticamente compactadas nos espaços finais e prefixados. See 'Sintaxe CREATE INDEX'.

Índices são utilizados nos seguintes modos:

Suponha que você utilize a seguinte instrução SELECT:

mysql> SELECT * FROM nome_tabela WHERE col1=val1 AND col2=val2;

Se um índice de colunas múltiplas existir em col1 e col2, os registros apropriados podem ser recuperados diretamente. Se índices separados de únicas colunas existirem em col1 e col2, o otimizador tentará encontrar o índice mais restritivo decidindo qual índice irá encontrar menos registros e usará este índice para recuperar os registros.

Se a tabela possuir um índice de múltiplas colunas, qualquer prefixo mais à esquerda do índice pode ser usado pelo otimizador para encontrar registros. Por exemplo, se você possui um índice de três colunas em (col1, col2, col3), você tem capacidades de busca indexada em (col1), (col1, col2) e (col1, col2, col3).

O MariaDB não pode utilizar um índice parcial se as colunas não formarem um prefixo mais à esquerda do índice. Suponha que você tenha as instruções SELECT mostradas abaixo:

mysql> SELECT * FROM nome_tabela WHERE col1=val1;
mysql> SELECT * FROM nome_tabela WHERE col2=val2;
mysql> SELECT * FROM nome_tabela WHERE col2=val2 AND col3=val3;

Se um índice existir em (col1, col2, col3), somente a primeira consulta anteriores utiliza o índice. A segunda e terceira consultas involvem colunas indexadas, mas (col2) e (col2, col3) não são os prefixos mais à esquerda de (col1, col2, col3).

O MariaDB também utiliza índices para comparações do tipo LIKE se o argumento para LIKE for uma string constante que não inicie com um meta caracter Por exemplo as seguintes instruções SELECT utilizam índices:

mysql> SELECT * FROM nome_tbl WHERE key_col LIKE 'Patrick%';
mysql> SELECT * FROM nome_tbl WHERE key_col LIKE 'Pat%_ck%';

Na primeira instrução, somente os registros com 'Patrick' <= key_col < 'Patricl' são considerados. Na segunda instrução, somente registros com 'Pat' <= key_col < 'Pau' são considerados.

As seguintes instruções SELECT não usarão índices:

mysql> SELECT * FROM nome_tbl WHERE key_col LIKE '%Patrick%';
mysql> SELECT * FROM nome_tbl WHERE key_col LIKE other_col;

Na primeira instrução, o valor LIKE inicia com um meta caracter. Na segunda instrução, o valor LIKE não é uma constante.

O MariaDB faz outra otimização em LIKE. Se você usar ... LIKE '%string%' e string tiver mais de 3 caracteres, o MariaDB usará o algorítmo Turbo Boyer-Moore para inicializar o padrão para a string e então usar este padrão para realizar a pesquisa mais rápido.

Buscas usando nome_coluna IS NULL usa índices se nome_coluna é um índice.

O MariaDB normalmente utiliza o índice que encontra o menor número de registros. Um índice é usado para colunas que você compara com os seguintes operadores: =, >, >=, <, <=, BETWEEN ou um LIKE com um padrão que começa com um prefixo sem meta caracteres como 'algo%'.

Qualquer índice que não cobrem todos os níveis de AND na cláusula WHERE não é utilizado para otimizar a consulta. Em outras palavras: Para poder usar um índice, um prefixo do índice deve ser utilizado em todo agrupamento AND.

A seguinte cláusula WHERE utilizará índices:

... WHERE index_part1=1 AND index_part2=2 AND other_column=3
... WHERE index=1 OR A=10 AND index=2 /* index = 1 OR index = 2 */
... WHERE index_part1='hello' AND index_part_3=5
 /* optimised like 'index_part1='hello'' */
... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;
 /* Can use index on index1 but not on index2 or index 3 */

Estas cláusulas WHERE não utilizam índices:

... WHERE index_part2=1 AND index_part3=2 /* index_part_1 is not used */
... WHERE index=1 OR A=10 /* Index is not used in
 both AND parts */
... WHERE index_part1=1 OR index_part2=10 /* No index spans all rows */

Perceba que algumas vezes o MariaDB não utilizará um índice, mesmo se algum estiver disponível. Um exemplo deste caso é quando o uso do índice necessita que o MariaDB acesse mais de 30% dos registros na tabela. (Neste caso uma varredura da tabela é provavelmente mais rápido, já que ela necessitará de menos pesquisas em discos). No entanto, se uma consulta utiliza LIMIT para recuperar somente parte dos registros, o MariaDB irá utilizar um índice de qualquer forma, pois assim pode encontrar os poucos registros mais rapidamente e retornar o resultado.

Índices de Colunas

Todos os tipos de colunas do MariaDB podem ser indexadas. O uso de índices nas colunas relevantes é a melhor forma de melhorar a performance de operações SELECT.

O número máximo de índices por tabelas e o tamanho máximo de um índice é definido pelo mecanismo de armazenamento. Leia Tipos de Tabela do MariaDB. Todos os mecanismos de armazenamentos suportam um mínimo de 16 chaves por tabela e um índice de tamanho total mínimo de 256 bytes.

Para colunas CHAR e VARCHAR você pode indexar um prefixo da coluna. Isto é muito mais rápido e necessita de menos espaço em disco do que indexar a coluna inteira. A sintaxe para utilizar na instrução CREATE TABLE para indexar um prefixo de uma coluna se parece com o exemplo a seguir:

INDEX nome_indice (nome_campo(tamanho))

O exemplo abaixo cria um índice para os primeiros 10 caracteres da coluna nome:

mysql> CREATE TABLE teste (
 nome CHAR(200) NOT NULL,
 INDEX nome_indice (nome(10)));

Para colunas BLOB e TEXT, você deve indexar um prefixo da coluna. O índice pode ter até 255 bytes.

No MariaDB Versão 3.23.23 ou posterior, você pode também criar índices FULLTEXT especiais. Eles são utilizados para pesquisas textuais. Somente o tipo de tabela MyISAM suporta índices FULLTEXT e apenas para colunas CHAR, VARCHAR e TEXT. Indexação sempre acontece sobre toda a coluna e indexação parcial (prefixo) não é suportada. Veja 'Pesquisa Full-text no MySQL' para detalhes.

Índices de Múltiplas Colunas

O MariaDB pode criar índices em múltiplas colunas. Um índice pode consistir de até 15 colunas. (Em colunas CHAR e VARCHAR você também pode utilizar um prefixo da coluna como parte de um índice).

Um índice de múltiplas colunas pode ser considerado um array ordenado contendo valores que são criados concatenando valores de colunas indexadas.

O MariaDB utiliza índices de múltiplas colunas de forma que consultas são rápidas quando você especifica uma quantidade conhecida para a primeira coluna do índice em uma cláusula WHERE, mesmo se você não especificar valores para as outras colunas.

Suponha que uma tabela tenha a seguinte especificação:

mysql> CREATE TABLE teste (
 id INT NOT NULL,
 ultimo_nome CHAR(30) NOT NULL,
 primeiro_nome CHAR(30) NOT NULL,
 PRIMARY KEY (id),
 INDEX nome (ultimo_nome,primeiro_nome));

Então o índice nome é um índice com ultimo_nome e primeiro_nome. O índice será usado para consultas que especificarem valores em um limite conhecido para ultimo_nome, ou para ambos ultimo_nome e primeiro_nome. Desta forma, o índice nome será usado nas seguintes consultas:

mysql> SELECT * FROM teste WHERE ultimo_nome='Widenius';
mysql> SELECT * FROM teste WHERE ultimo_nome='Widenius'
 AND primeiro_nome='Michael';
mysql> SELECT * FROM teste WHERE ultimo_nome='Widenius'
 AND (primeiro_nome='Michael' OR primeiro_nome='Monty');
mysql> SELECT * FROM teste WHERE ultimo_nome='Widenius'
 AND primeiro_nome >='M' AND primeiro_nome < 'N';

Entretanto, o índice nome não será usado nas seguintes consultas:

mysql> SELECT * FROM teste WHERE primeiro_nome='Michael';
mysql> SELECT * FROM teste WHERE ultimo_nome='Widenius'
 OR primeiro_nome='Michael';

Para maiores informações sobre a maneira que o MariaDB utiliza índices para melhorar o desempenho das consultas, veja 'Como o MariaDB Utiliza Índices'.

Como o MariaDB Conta as Tabelas Abertas

Ao executar o comando mysqladmin status, você verá algo deste tipo:

Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12

O valor Open tables de 12 ode ser bastante estranho se você só possui 6 tabelas.

O MariaDB é multithreaded, portanto ele pode haver clientes enviando consultas para uma determinada tabela simultaneamente. Para minimizar o problema com dois clientes tendo diferentes estados no mesmo arquivo, a tabela é aberta independentemente por cada thread concorrente. Isto exige mais memória mas normalmente aumentará o desempenho. Com tabelas ISAM e MyISAM, um descritor extra de arquivo é necessário para o arquivo de dados, para cada cliente que tem a tabela aberta. O descritor de arquivo de índice é compartilhado entre todas as threads.

Você pode ler mais sobre este tópico na próxima seção. Leia 'Como o MariaDB Abre e Fecha as Tabelas'.

Como o MariaDB Abre e Fecha as Tabelas

As variáveis do servidor table_cache, max_connections e max_tmp_tables afetam o número máximo de arquivos que o servidor mantêm abertos. Se você aumentar um ou ambos destes valores, você pode ir contra um limite imposto pelo seu sistema operacional no número de arquivos abertos por processo. Você pode aumentar o limite de arquivos abertos em muitos sistemas operacionais, embora o método varia muito de um sistema para outro. Consulte a documentação de seu Sistema Operacional para saber como fazê-lo, porque o método para alterar o limite varia muito de um sistema para outro.

table_cache é relacionado a max_connections. Por exemplo, para 200 conexões concorrentes em execução, você deve ter um tamanho de cache de tabela de pelo menos * n, onde n é o número máximo de tabelas em um join. Você também precisa reservar alguns descritores de arquivos para tabelas e arquivos temporários.

Esteja certo de que o seu sistema operacional pode tratar o número de descritores de arquivos abertos definido pelo valor de table_cache. Se table_cache for muito alto, o MariaDB pode esgotar os descritores de arquivo e recusar conexões, falhar na execução de consultas e ser muito instavel. Você também têm que levar em conta que o mecanismo de armazenamento MyISAM precisa de dois descritores de arquivos para cada tabela aberta. Você pode aumentar o número de descritores de arquivo disponíveis para o MariaDB com a opção de inicialização --open-files-limit=#. Leia Seção A.2.17, 'Arquivo Não Encontrado'.

A cache de tabelas abertas será mantido em um nível de table_cache entradas. O valor padrão é 64; isto pode ser alterado com a opção -O table_cache=# do mysqld. Note que o MariaDB pode temporariamente abrir mais tabelas para poder se executar consultas.

Um tabela não usada é fechada e removida da cache de tabelas sob as seguintes circuntâncias:

Quando o cache de tabela encher, o servidor usa o seguinte procedimento para encontrar uma entrada de cache para usar:

A table is opened for each concurrent access. This means the table needs to be opened twice if two threads access the same table or if a thread accesses the table twice in the same query (for example, by joining the table to itself).

Uma tabela é aberta para cada acesso simultâneo. Isto significa a tabela precisa ser aberta duas vezes se duas threads acessam a mesma tabela ou se uma thread acessa a tabela duas vezes na mesma consulta (por exemplo, fazendo um join da tabela com ela mesma). A primeira abertura de qualquer tabela exige dois descritores de arquivos; cada uso adicional da tabela exige somente um descritor. O descritor extra para a primeira abertura é para o arquivo de índice: este descritor é compartilhado entre todas as threads.

Se você está abrindo uma tabela com a instrução HANDLER nome_tabela OPEN, uma tabela dedicada é alocada para a thread. Este objeto da tabela não é compartilhado por outras threads e não será fechado até que a thread chame HANDLER nome_tabela CLOSE ou seja finalizada. Leia 'Sintaxe HANDLER'. Quando isto acontece, a tabela é colocada de volta na cache de tabela (se a cache não estiver cheia).

Você pode conferir se o seu cache de tabela está muito pequeno conferindo a variável opened_tables do mysqld. Se este valor for muito grande, mesmo se você não fez vários FLUSH TABLES, você deve aumentar o tamanho da sua cache de tabelas. Leia 'SHOW STATUS'.

Desvantagem em Criar um Número Grande de Tabelas no Mesmo Banco de Dados

Se você possui muitos arquivos em um diretório, operações de abrir, fechar e criação ficarão lentos. Se você executar instruções SELECT em diversas tabelas, existirá uma pequena sobrecarga quando o cache de tabela estiver cheio, porque para toda tabela que teve que ser aberta, outra deve ser fechada. Você pode reduzir esta sobrecarga tornando o cache de tabelas maior.

Otimizando o Servidor MariaDB

Sintonia dos Parâmetros em Tempo de Sistema/Compilação e na Inicialização
Parâmetros de Sintonia do Servidor
Como a Compilação e a Ligação Afetam a Velocidade do MariaDB
Como o MariaDB Utiliza a Memória
Como o MariaDB Utiliza o DNS
Sintaxe de SET

Sintonia dos Parâmetros em Tempo de Sistema/Compilação e na Inicialização

Nós iniciamos com o fator do nível do sistema pois algumas destas decisões devem ser feitas bem cedo. Em outros casos uma rápida olhada para esta seção pode satisfazer porque ela não é tão importante para os grandes ganhos. Entretanto, é sempre bom ter ter noções de como você pode obter melhorias alterando coisas neste nível.

Qual sistema operacional a usar é realmente importante! Para obter o melhor uso de máquinas com múltiplas CPUs você deve utilizar Solaris (porque a sua implemetação das threads funcionam muito bem) ou Linux (porque o kernel 2.2 tem suporte SMP muito bom). Também, em Linux mais antigos temos o limite de tamanho de arquivo de 2G por padrão. Se você tem tal kernel e precisa desesperadamente de trabalhar com arquivos maiores que 2G em máquinas intel Linux, você deve obter o patch LFS para o sistema de arquivos ext2. Outros sistemas de arquivo como ReiserFS e XFS não possuem esta limitação de 2G.

Como ainda não temos o MariaDB em produção em muitas outras plataformas, nós aconselhamos que você teste a plataforma pretendida antes de escolhe-la, se possível.

Outras dicas:

Parâmetros de Sintonia do Servidor

Você pode determinar tamanho padrão do buffer usados pelo servidor mysqld com este comando:

shell> mysqld --help

Este comando produz uma lista de todas as opções do mysqld e variáveis configuráveis. A saída inclui os valores padrão das variáveis e se parece com isto:

back_log current value: 5
bdb_cache_size current value: 1048540
binlog_cache_size current value: 32768
connect_timeout current value: 5
delayed_insert_timeout current value: 300
delayed_insert_limit current value: 100
delayed_queue_size current value: 1000
flush_time current value: 0
interactive_timeout current value: 28800
join_buffer_size current value: 131072
key_buffer_size current value: 1048540
lower_case_nome_tabelas current value: 0
long_query_time current value: 10
max_allowed_packet current value: 1048576
max_binlog_cache_size current value: 4294967295
max_connections current value: 100
max_connect_errors current value: 10
max_delayed_threads current value: 20
max_heap_table_size current value: 16777216
max_join_size current value: 4294967295
max_sort_length current value: 1024
max_tmp_tables current value: 32
max_write_lock_count current value: 4294967295
myisam_sort_buffer_size current value: 8388608
net_buffer_length current value: 16384
net_retry_count current value: 10
net_read_timeout current value: 30
net_write_timeout current value: 60
read_buffer_size current value: 131072
record_rnd_buffer_size current value: 262144
slow_launch_time current value: 2
sort_buffer current value: 2097116
table_cache current value: 64
thread_concurrency current value: 10
tmp_table_size current value: 1048576
thread_stack current value: 131072
wait_timeout current value: 28800

Se existir um servidor mysqld em execução, você pode ver quais valores ele está usando atualmente para as variáveis executando esta instrução:

mysql> SHOW VARIABLES;

Você também pode ver algumas estatísticas e indicadores de status para um servidor em execução executando este comando:

mysql> SHOW STATUS;

Para encontrar uma descrição completa de todas as variáveis na seção SHOW VARIABLES neste manual. Leia 'SHOW VARIABLES'.

Para informação sobre variáveis de estado, veja 'SHOW STATUS'.

Variáveis de servidor e informação de status também pode ser obtido usando mysqladmin:

shell> mysqladmin variables
shell> mysqladmin extended-status

O MariaDB utiliza algorítmos que são muito escaláveis, portanto, normalmente você pode trabalhar com pouca memória. Entretanto, se você fornecer ao MariaDB mais memória, obterá um desempenho melhor.

Quando estiver ajustando um servidor MySQL, as duas variáveis mais importantes que devem ser usadas são key_buffer_size e table_cache. Você deve se sentir confiante que as duas estejam corretas antes de tentar alterar qualquer outra variável.

Os seguintes exemplos indicam alguns valores típicos de variáveis para diferentes configurações de tempo de execução. Os exemplos usam o script mysqld_safe e usam a sintaxe --name=value para definir a variável name com o valor value. Esta sintaxe está disponível a partir do MariaDB 4.0. Para versões mais antigas do MariaDB, tome as seguintes diferenças nas contas:

Se você possui pelo menos 256M de memória e várias tabelas e deseja obter o melhor desempenho com um número moderado de clientes, deve utilizar algo como:

shell> mysqld_safe --key_buffer_size=64M --table_cache=256 \
 --sort_buffer_size=4M --read_buffer_size=1M &

Se possui apenas 128M de memória e apenas algumas poucas tabelas, mas ainda deseja realizar várias ordenações, você pode utilizar:

shell> mysqld_safe --key_buffer_size=16M --sort_buffer_size=1M

Se você possuir pouca memória e tiver muitas conexões, utilize algo como:

shell> mysqld_safe --key_buffer_size=512K --sort_buffer_size=100K \
 --read_buffer_size=100K &

ou mesmo isto:

shell> mysqld_safe --key_buffer_size=512K --sort_buffer_size=16K \
 --table_cache=32 --read_buffer_size=8K -O net_buffer_length=1K &

Se você estiver executando um GROUP BY ou ORDER BY em tabelas que são muito maiores que sua memória disponível você deve aumentar o valor de record_rnd_buffer_size para acelerar a leitura de registros após a operação de ordenação.

Quando você tiver instalado o MySQL, o diretório support-files irá conter alguns arquivos exemplos do my.cnf, my-huge.cnf, my-large.cnf, my-medium.cnf e my-small.cnf, você pode usá-los como base para otimizar seu sistema.

Se você possui várias conexões simultâneas, problemas de trocas podem ocorrer a menos que o mysqld tenha sido configurado para usar muito pouca memória para cada conexão. O mysqld tem melhor performance se você tiver memória suficiente para todas as conexões, é claro.

Perceba que se você especifica uma opção na linha de comando para o mysqld, ou mysqld_safe ele permanece em efeito somente para aquela chamada do servidor. Para usar a opção toda vez que o servidor executa, coloque-o em um arquivo de opção.

Para ver os efeitos de uma alteração de parâmetro, faça algo como:

shell> mysqld --key_buffer_size=32m --help

Tenha certeza que a opção --help seja a última do comando; de outra forma o efeito de qualquer opções listadas depois na linha de comando não serão refletidas na saída.

Como a Compilação e a Ligação Afetam a Velocidade do MariaDB

A maioria dos testes seguintes são feitos no Linux com os benchmarks do MariaDB, mas eles devem fornecer alguma indicação para outros sistemas operacionais e workloads.

Você obtêm um executável mais veloz quando ligado com -static.

No Linux, você irá obter o código mais rápido quando compilando com pgcc e -03. Para compilar sql_yacc.cc com estas opções, você precisa de cerca de 200M de memória porque o gcc/pgcc precisa de muita memória para criar todas as funções em linha. Também deve ser configurado o parâmetro CXX=gcc para evitar que a biblioteca libstdc++ seja incluida (não é necessária). Perceba que com algumas versões do pgcc, o código resultante irá executar somente em verdadeiros processadores Pentium, mesmo que você utilize a opção do compilador para o código resultante que você quer, funcionando em todos os processadores do tipo x586 (como AMD).

Só pelo fato de utilizar um melhor compilador e/ou melhores opções do compilador você pode obter um aumento de desempenho de 10-30% na sua aplicação. Isto é particularmente importante se você mesmo compila o servidor SQL!

Nós testamos ambos os compiladores Cygnus Codefusion e o Fujitsu, mas quando os testamos, nenhum dos dois era suficientemente livre de erros para que o MariaDB compilasse com as otimizações.

Quando você compila o MariaDB deve incluir suporte somente para os conjuntos de caracteres que deseja usar. (Opção --with-charset=xxx). As distribuições binárias padrão do MariaDB são compiladas com suporte para todos os conjuntos de caracteres.

Segue uma lista de algumas medidas que temos feito:

A distribuição MySQL-Linux fornecida pela MariaDB Foundation é normalmente compilada com pgcc, mas vamos retornar ao uso do gcc pelo fato de um bug no pgcc que gera o código que não executa no AMD. Continuaremos a usar o gcc até que o bug seja resolvido. Neste meio tempo, se você possui uma máquina que não seja AMD, você pode ter um binário mais rápido compilando com o pgcc. O binário padrão do MariaDB para Linux é ligado estaticamente para conseguir mais desempenho e ser mais portável.

Como o MariaDB Utiliza a Memória

A lista abaixo indica algumas das maneiras inas quais o servidor mysqld utiliza a memória. Onde aplicável, o nome da variável do servidor relevante ao uso de memória é fornecido:

ps e outros programas de informações do sistema podem relatar que o mysqld usa muita memória. Isto pode ser causado pelas pilhas de threads em diferentes endereços de memória. Por exemplo, a versão do ps do Solaris conta a memória não usada entre as pilhas como memória usada. Você pode verificar isto conferindo a memória disponível com swap -s. Temos testado o mysqld com detectores comerciais de perda de memória, portanto tais perdas não devem existir.

Como o MariaDB Utiliza o DNS

Quando um novo cliente conecta ao mysqld, o mysqld extende uma nova thread para lidar com o pedido. Esta thread primeiro confere se o nome da máquina está no cache de nomes de máquinas. Se não, a thread tenta resolver o nome da máquina.

Você pode desabilitar a procura de nomes de máquinas no DNS iniciando o mysqld com a opção --skip-name-resolve. No entanto, neste caso você só pode usar números IP nas tabelas de privilégio do MariaDB.

Se você possuir um DNS muito lento e várias máquinas, pode obter mais desempenho desligando a procura de nomes de máquinas usando a opção --skip-name-resolve ou aumentando HOST_CACHE_SIZE (valor padrão: 128) e recompilar mysqld.

Você pode desabilitar o cache de nomes de máquinas iniciando o servidor com a opção --skip-host-cache. Para limpar a cache do nome de máquinas, envie uma instru;ção FLUSH HOSTS ou execute o comando mysqladmin flush-hosts.

Se você deseja disabilitar as conexões TCP/IP totalmente, inicie o mysqld com a opção --skip-networking.

Sintaxe de SET

SET [GLOBAL | SESSION] sql_variable=expression,
 [[GLOBAL | SESSION] sql_variable=expression] ...

SET configura várias opções que afetam a operação do servidor ou seu cliente.

Os seguintes exemplos mostram as diferentes sintaxes que se pode usar para configurar variáveis:

Em versões antigas do MariaDB permitiamos o uso da sintaxe SET OPTION, mas esta sintaxe agora está obsoleta.

No MariaDB 4.0.3 adicionamos as opções GLOBAL e SESSION e acessamos as variáveis de inicialização mais importantes.

LOCAL pode ser usado como sinôniumo de SESSION.

Se você define diversas variáveis na mesma linha de comando, o último modo GLOBAL | SESSION é utilizado

SET sort_buffer_size=10000;
SET @@local.sort_buffer_size=10000;
SET GLOBAL sort_buffer_size=1000000, SESSION sort_buffer_size=1000000;
SET @@sort_buffer_size=1000000;
SET @@global.sort_buffer_size=1000000, @@local.sort_buffer_size=1000000;

A sintaxe @@nome_variável é suoprtada para tornar a sintaxe do MariaDB compatível com outros bancos de dados.

As diferentes variáveis de sistema que podem ser configuradas estão descritas na seção de variáveis de sistema deste manual. Leia 'Variáveis de Sistema'.

Se você estiver usando SESSION (o padrão) a opção que você definir terá efeito até que o sessão atual finalize ou até que vecê atribua um valor diferente a esta opção. Se você estiver usando GLOBAL, que exige o privilégio SUPER, a opção é lembrada e usada pelas novas conexões até que o servidor reinicie. Se você quiser tornar uma opção permanente, você deve definí-la em um arquivo de opção. See 'Arquivo de Opções my.cnf'.

Para evitar o uso incorreto, o MariaDB exibirá um erro se você usar SET GLOBAL com uma variável que só pode ser usada com SET SESSION ou se você não estiver usando SET GLOBAL com uma variável global.

Se você quiser definir uma variável SESSION com um valor GLOBAL ou um valor GLOBAL ao valor padrão do MariaDB, você pode configurá-lo com DEFAULT.

SET max_join_size=DEFAULT;

Isto é idêntico a:

SET @@session.max_join_size=@@global.max_join_size;

Se você quiser restringir o valor máximo com o qual uma variável de servidor pode ser configurado com o comando SET, você pode especificaá-lo usando a opção de linha de comando --maximum-variable-name. Leia 'Opções de Linha de Comando do mysqld'.

Você pode obter uma lista da maioria das variáveis com SHOW VARIABLES. Leia 'SHOW VARIABLES'. Você pode obter o valor de uma variável específica com a sintaxe @@[global.|local.]variable_name:

SHOW VARIABLES like 'max_join_size';
SHOW GLOBAL VARIABLES like 'max_join_size';
SELECT @@max_join_size, @@global.max_join_size;

Segue aqui a descrição das variáveis que usam uma sintaxe SET não padrão e algumas das outras variáveis. A definição das outras variáveis podem ser encontrados na seção variáveis de sistema, entre as opções de inicialização ou na descrição de SHOW VARIABLES. Leia 'Variáveis de Sistema'. Leia 'Opções de Linha de Comando do mysqld'. Leia 'SHOW VARIABLES'.

Detalhes de Disco

Utilizando Links Simbólicos

Utilizando Links Simbólicos

Utilizando Links Simbólicos para Bancos de Dados
Utilizando Links Simbólicos para Tabelas
Usando Links Simbólicos para Bancos de Dados no Windows

Você pode mover tabelas e bancos de dados do diretório de banco de dados para outras localizações e trocá-los por links simbólicas para os novos locais. Você pode fazer isto, por exemplo, para mover um banco de dados para um sistema de arquivos com mais espaço livre ou aumentar a velocidade de seu sistema esipalhando suas tabelas para discos diferentes.

A maneira recomendada de se fazer isto é ligar simbolicamente bancos de dados a discos diferentes e só ligar tabelas como último recurso.

Utilizando Links Simbólicos para Bancos de Dados

No Unix, a maneira de ligar simbolicamente um banco de dados é, primeiramente, criar um diretório em algum disco onde você possui espaço livre e então criar uma ligação simbólica para ele a partir do diretório do banco de dados do MariaDB.

shell> mkdir /dr1/databases/test
shell> ln -s /dr1/databases/test mysqld-datadir

O MariaDB não suporta que você ligue um diretório a vários bancos de dados. Trocando um diretório de banco de dados com uma ligação simbólica irá funcionar bem desde que não sejam feitos links simbólicos entre os bancos de dados. Suponha que você tenha um banco de dados db1 sob o diretório de dados do MariaDB, e então criar uma ligação simbólica db2 que aponte para db1.

shell> cd /caminho/para/diretorio/dados
shell> ln -s db1 db2

Agora, para qualquer tabela tbl_a em db1, também aparecerá uma tabela tbl_a em db2. Se uma thread atualizar db1.tbl_a e outra atualizar db2.tbl_a, ocorrerão porblemas.

Se você realmente precisar disto, você deve alterar o código seguinte em mysys/mf_format.c:

if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode)))

para

if (1)

No Windows você pode utilizar links simbólicos para diretórios compilando o MariaDB com -DUSE_SYMDIR. Isto lhe permite colocar diferentes bancos de dados em discos diferentes. Leia 'Usando Links Simbólicos para Bancos de Dados no Windows'.

Utilizando Links Simbólicos para Tabelas

Antes do MariaDB você não deve utilizar tabelas com ligações simbólicas, se você não tiver muito cuidado com as mesmas. O problema é que se você executar ALTER TABLE, REPAIR TABLE ou OPTIMIZE TABLE em uma tabela ligada simbolicamente, os links simbólicos serão removidas e substituidos pelos arquivos originiais. Isto acontece porque o comando acima funcinoa criando um arquivo temporário no diretório de banco de dados e quando o comando é completo, substitui o arquivo original pelo arquivo temporário.

Você não deve ligar simbolicamente tabelas em um sistema que não possui uma chamada realpath() completa. (Pelo menos Linux e Solaris suportam realpath()

No MariaDB links simbólicos só são suportados completamente por tabelas MyISAM. Para outros tipos de tabelas você provavelmente obterá problemas estranhos ao fazer qualquer um dos comandos mencionados acima.

O tratamento de links simbólicos no MariaDB funciona da seguinte maneira (isto é mais relevante somente para tabelas MyISAM.

O que ainda não é suportado:

Usando Links Simbólicos para Bancos de Dados no Windows

A partir do MariaDB versão 3.23.16, o mysqld-max e servidores mysql-max-nt na distribuição MariaDB são compilados com a opção -DUSE_SYMDIR. Isto permite que você coloque um diretório de banco de dados em discos diferentes adicionando um link simbólico para ele. (Isto é parecido com o a com que links simbólicos funcionam no Unix, embora o procedimento para configurar o link seja diferente).

No Windows, você cria um link simbólico para um banco de dados MariaDB criando um arquivo que contem o caminho para o diretório de destino. Salve o arquivo no diretório de dados usando o nome de arquivo nome_bd.sym, onde nome_bd é o nome do banco de dados.

Por exemplo, se o diretório de dados do MariaDB é C:\mysql\data e você precisa ter o banco de dados foo localizado em D:\data\foo, você deve criar o arquivo C:\mysql\data\foo.sym que contêm o caminho D:\data\foo\. Depois disto, todas tabelas criadas no banco de dados foo serão criadas no D:\data\foo. O diretório D:\data\foo deve existir para ele funcionar. Note também que o link simbólico não será usado se um diretório com o nome do banco de dados existe no diretório de dados MySQL. Isto significa que se você já tem um diretório de banco de dados chamado foo no direorio de dados, você deve movê-lo para D:\data antes do link simbólico ser efetivado. (Para evitar problemas, o servidor não deve estar executando quando você mover o diretório do banco de dados.)

Note que devido a penalidade que você tem na velocidade quando abre todas as tabelas, nós não habilitamos esta opção por padrão, mesmo se você compilar o MariaDB com suporte a isto. Para habilitar links simbólicos você deve colocar no seu arquivo my.cnf ou my.ini a seguinte entrada:

[mysqld]
symbolic-links

No MariaDB --simbolic-links está habilitado por padrão. Se você não precisa usá-lo você pode usar a opção skip-symbolic-linkd.



Anterior Próximo
Administração do Bancos de Dados MySQL Início Referência de Linguagem do MariaDB