Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Recursos ocultos do MySQL


Desde que você colocou uma recompensa, vou compartilhar meus segredos conquistados com muito esforço...

Em geral, todos os SQLs que ajustei hoje exigiam o uso de subconsultas. Tendo vindo do mundo do banco de dados Oracle, as coisas que eu dava como garantidas não estavam funcionando da mesma forma com o MySQL. E minha leitura sobre o ajuste do MySQL me faz concluir que o MySQL está atrás do Oracle em termos de otimização de consultas.

Embora as consultas simples necessárias para a maioria dos aplicativos B2C possam funcionar bem para o MySQL, a maioria do tipo de relatório agregado de consultas necessárias para o Intelligence Reporting parece exigir um pouco de planejamento e reorganização das consultas SQL para orientar o MySQL a executá-las mais rapidamente.

Administração:


max_connections é o número de conexões simultâneas. O valor padrão é 100 conexões (151 desde 5.0) - muito pequeno.

Observação:

conexões consomem memória e seu sistema operacional pode não ser capaz de lidar com muitas conexões.

Os binários do MySQL para Linux/x86 permitem que você tenha até 4.096 conexões simultâneas, mas os binários autocompilados geralmente têm um limite menor.

Defina table_cache para corresponder ao número de suas tabelas abertas e conexões simultâneas. Observe o valor open_tables e se ele estiver crescendo rapidamente, você precisará aumentar seu tamanho.

Observação:

Os 2 parâmetros anteriores podem exigir muitos arquivos abertos. 20+max_connections+table_cache*2 é uma boa estimativa para o que você precisa. MySQL no Linux tem uma opção open_file_limit, defina este limite.

Se você tiver consultas complexas, sort_buffer_size e tmp_table_size provavelmente serão muito importantes. Os valores dependerão da complexidade da consulta e dos recursos disponíveis, mas 4Mb e 32Mb, respectivamente, são pontos de partida recomendados.

Nota:Estes são valores "por conexão", entre read_buffer_size, read_rnd_buffer_size e alguns outros, o que significa que este valor pode ser necessário para cada conexão. Portanto, considere sua carga e recurso disponível ao definir esses parâmetros. Por exemplo, sort_buffer_size é alocado apenas se o MySQL precisar fazer uma classificação. Nota:tenha cuidado para não ficar sem memória.

Se você tiver muitas conexões estabelecidas (ou seja, um site sem conexões persistentes), poderá melhorar o desempenho configurando thread_cache_size para um valor diferente de zero. 16 é um bom valor para começar. Aumente o valor até que seus threads_created não cresçam muito rapidamente.

CHAVE PRIMÁRIA:


Pode haver apenas uma coluna AUTO_INCREMENT por tabela, ela deve ser indexada e não pode ter um valor DEFAULT

KEY normalmente é sinônimo de INDEX. O atributo de chave PRIMARY KEY também pode ser especificado como apenas KEY quando fornecido em uma definição de coluna. Isso foi implementado para compatibilidade com outros sistemas de banco de dados.

A PRIMARY KEY é um índice exclusivo em que todas as colunas de chave devem ser definidas como NOT NULL

Se um índice PRIMARY KEY ou UNIQUE consiste em apenas uma coluna que possui um tipo inteiro, você também pode se referir à coluna como "_rowid" em instruções SELECT.

No MySQL, o nome de uma PRIMARY KEY é PRIMARY

Atualmente, apenas as tabelas InnoDB (v5.1?) suportam chaves estrangeiras.

Normalmente, você cria todos os índices necessários ao criar tabelas. Qualquer coluna declarada como PRIMARY KEY, KEY, UNIQUE ou INDEX será indexada.

NULL significa "sem valor". Para testar NULL, você não pode use os operadores de comparação aritmética como =, . Use os operadores IS NULL e IS NOT NULL:

NO_AUTO_VALUE_ON_ZERO suprime o incremento automático para 0 para que apenas NULL gere o próximo número de sequência. Este modo pode ser útil se 0 foi armazenado na coluna AUTO_INCREMENT de uma tabela. (A propósito, armazenar 0 não é uma prática recomendada.)

Para alterar o valor do contador AUTO_INCREMENT a ser usado para novas linhas:
ALTER TABLE mytable AUTO_INCREMENT = value; 

ouSET INSERT_ID =valor;

A menos que especificado de outra forma, o valor começará com:1000000 ou especificá-lo assim:

...) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1

TIMESTAMPS:


Os valores das colunas TIMESTAMP são convertidos do fuso horário atual para UTC para armazenamento e de UTC para o fuso horário atual para recuperação.

http://dev.mysql.com/doc/refman/5.1 /en/timestamp.html Para uma coluna TIMESTAMP em uma tabela, você pode atribuir o timestamp atual como o valor padrão e o valor de atualização automática.

uma coisa a observar ao usar um desses tipos em uma cláusula WHERE, é melhor fazerWHERE datecolumn =FROM_UNIXTIME (1057941242) e não WHERE UNIX_TIMESTAMP (datecolumn) =1057941242. coluna.

http://dev.mysql.com /doc/refman/5.1/en/date-and-time-functions.html
 UNIX_TIMESTAMP() 
 FROM_UNIXTIME() 
 UTC_DATE()
 UTC_TIME()
 UTC_TIMESTAMP()

se você converter um datetime para timestamp unix no MySQL:
E então adicione 24 horas a ele:
E então converta de volta para um datetime ele magicamente perde uma hora!

Aqui está o que está acontecendo. Ao converter o timestamp unix de volta para um datetime, o fuso horário é levado em consideração e acontece que entre os dias 28 e 29 de outubro de 2006, saímos do horário de verão e perdemos uma hora.

A partir do MySQL 4.1.3, as funções CURRENT_TIMESTAMP(), CURRENT_TIME(), CURRENT_DATE() e FROM_UNIXTIME() retornam valores no fuso horário atual da conexão , que está disponível como o valor da variável de sistema time_zone. Além disso, UNIX_TIMESTAMP() assume que seu argumento é um valor de data e hora no fuso horário atual.

A configuração de fuso horário atual não afeta os valores exibidos por funções como UTC_TIMESTAMP() ou valores nas colunas DATE, TIME ou DATETIME.

NOTA:NA ATUALIZAÇÃO SOMENTE atualiza o DateTime se um campo for alterado Se um UPDATE resultar em nenhum campo sendo alterado, o DateTime NÃO será atualizado!

Além disso, o primeiro TIMESTAMP é sempre AUTOUPDATE por padrão, mesmo que não seja especificado

Ao trabalhar com datas, quase sempre converso com a data juliana porque a matemática de dados é uma simples questão de adicionar ou subtrair inteiros e segundos desde a meia-noite pelo mesmo motivo. É raro eu precisar de resolução de tempo de granularidade mais fina do que segundos.

Ambos podem ser armazenados como um inteiro de 4 bytes e, se o espaço for muito apertado, podem ser combinados no tempo UNIX (segundos desde a época 1/1/1970) como um inteiro sem sinal que será bom até por volta de 2106 como:

' segundos em 24 horas =86400

' Signed Integer max val =2.147.483.647 - pode conter 68 anos de segundos

' Valor máximo de inteiro sem sinal =4.294.967.295 - pode conter 136 anos de segundos

Protocolo binário:


O MySQL 4.1 introduziu um protocolo binário que permite que valores de dados não string sejam enviados e retornados em formato nativo sem conversão de e para o formato string. (Muito útil)

Além disso, mysql_real_query() é mais rápido que mysql_query() porque não chama strlen() para operar na string de instrução.

http://dev.mysql.com/tech-resources /articles/4.1/prepared-statements.html O protocolo binário suporta instruções preparadas do lado do servidor e permite a transmissão de valores de dados em formato nativo. O protocolo binário passou por algumas revisões durante as versões anteriores do MySQL 4.1.

Você pode usar a macro IS_NUM() para testar se um campo tem um tipo numérico. Passe o valor do tipo para IS_NUM() e ele será avaliado como TRUE se o campo for numérico:

Uma coisa a notar é que os dados binários podem ser enviado dentro de uma consulta regular se você escapar e lembrar que o MySQL requer somente que a barra invertida e o caractere de aspas sejam escapados. Portanto, essa é uma maneira realmente fácil de INSERIR strings binárias mais curtas, como senhas criptografadas/salgadas, por exemplo.

Servidor mestre:


http://www.experts-exchange.com/Database/MySQL/Q_22967482 .html

http://www.databasejournal.com/features/mysql/article.php /10897_3355201_2

CONCEDER ESCRAVO DE REPLICAÇÃO EM . para slave_user IDENTIFICADO POR 'slave_password'
#Master Binary Logging Config  STATEMENT causes replication 
              to be statement-based -  default

log-bin=Mike
binlog-format=STATEMENT
server-id=1            
max_binlog_size = 10M
expire_logs_days = 120    


#Slave Config
master-host=master-hostname
master-user=slave-user
master-password=slave-password
server-id=2

O arquivo de log binário deve ler:

http://dev.mysql.com/doc/refman /5.0/en/binary-log.html

http://www.mydigitallife.info/2007/10/06/how-to-read-mysql-binary-log-files-binlog-with-mysqlbinlog/

http://dev.mysql.com/doc/refman/5.1 /en/mysqlbinlog.html

http://dev.mysql.com/doc/refman /5.0/en/binary-log.html

http://dev.mysql.com/doc /refman/5.1/en/binary-log-setting.html

Você pode excluir todos os arquivos de log binários com a instrução RESET MASTER ou um subconjunto deles com PURGE MASTER

--result-file=binlog.txt TrustedFriend-bin.000030

Normalização:


http://dev.mysql.com/tech-resources /articles/intro-to-normalization.html

Funções UDF


http://www.koders.com/cpp/fid10666379322B54AD41AEB0E4100D87C8CDDF1D8C.aspx

http://souptonuts.sourceforge.net/readme_mysql.htm

Tipos de dados:


http://dev.mysql.com/doc/refman /5.1/en/storage-requirements.html

http://www.informit.com/articles/article.aspx ?p=1238838&seqNum=2

http://bitfilm. net/2008/03/24/saving-bytes-efficient-data-storage-mysql-part-1/

Uma coisa a notar é que em uma tabela mista com CHAR e VARCHAR, o mySQL mudará os CHARs para VARCHARs

RecNum integer_type UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (RecNum)

O MySQL sempre representa as datas com o ano primeiro, de acordo com as especificações padrão SQL e ISO 8601

Diversos:


A desativação de algumas funcionalidades do MySQl resultará em arquivos de dados menores e acesso mais rápido. Por exemplo:

--datadir especificará o diretório de dados e

--skip-innodb desativará a opção inno e economizará 10 a 20 milhões

Mais aquihttp://dev.mysql.com/tech -resources/articles/mysql-c-api.html

Baixar Capítulo 7 - Gratuito

O InnoDB é transacional, mas há uma sobrecarga de desempenho que o acompanha. Descobri que as tabelas MyISAM são suficientes para 90% dos meus projetos. As tabelas não seguras para transações (MyISAM) têm várias vantagens próprias, todas elas ocorrem porque:

não há sobrecarga de transação:

Muito mais rapido

Menores requisitos de espaço em disco

Menos memória necessária para realizar atualizações

Cada tabela MyISAM é armazenada no disco em três arquivos. Os arquivos têm nomes que começam com o nome da tabela e possuem uma extensão para indicar o tipo de arquivo. Um arquivo .frm armazena o formato da tabela. O arquivo de dados tem uma extensão .MYD (MYData). O arquivo de índice tem uma extensão .MYI (MYIndex).

Esses arquivos podem ser copiado para um local de armazenamento intacto sem usar o recurso MySQL Administrators Backup, que é demorado (assim como a restauração)

O truque é fazer uma cópia desses arquivos e SOLTAR a tabela. Quando você colocar os arquivos de volta, o MySQl os reconhecerá e atualizará o rastreamento da tabela.

Se você precisar fazer Backup/Restaurar,

Restaurar um backup ou importar de um arquivo de despejo existente pode levar muito tempo, dependendo do número de índices e chaves primárias que você possui em cada tabela. Você pode acelerar esse processo drasticamente modificando seu arquivo de despejo original envolvendo-o com o seguinte:
SET AUTOCOMMIT = 0;
SET FOREIGN_KEY_CHECKS=0;

.. your dump file ..

SET FOREIGN_KEY_CHECKS = 1;
COMMIT;
SET AUTOCOMMIT = 1;

Para aumentar muito a velocidade do recarregamento, adicione o comando SQL SET AUTOCOMMIT =0; no início do arquivo de despejo e adicione o COMMIT; comando até o fim.

Por padrão, o autocommit está ativado, o que significa que cada comando de inserção no arquivo de despejo será tratado como uma transação separada e gravado no disco antes que o próximo seja iniciado. Se você não adicionar esses comandos, recarregar um banco de dados grande no InnoDB pode levar muitas horas...

O tamanho máximo de uma linha em uma tabela MySQL é 65.535 bytes

O comprimento máximo efetivo de um VARCHAR no MySQL 5.0.3 e em =tamanho máximo da linha (65.535 bytes)

Os valores VARCHAR não são preenchidos quando são armazenados. Os espaços à direita são retidos quando os valores são armazenados e recuperados, em conformidade com o SQL padrão.

Os valores CHAR e VARCHAR no MySQL são comparados sem considerar os espaços à direita.

Usar CHAR só vai acelerar seu acesso se todo o registro for de tamanho fixo. Ou seja, se você usar qualquer objeto de tamanho variável, você também pode torná-los todos de tamanho variável. Você não ganha velocidade usando um CHAR em uma tabela que também contém um VARCHAR.

O limite VARCHAR de 255 caracteres foi aumentado para 65535 caracteres a partir do MySQL 5.0.3

As pesquisas de texto completo são suportadas apenas para tabelas MyISAM.

http://dev.mysql.com/doc/refman /5.0/en/fulltext-search.html

As colunas BLOB não possuem conjunto de caracteres e a classificação e comparação são baseadas nos valores numéricos dos bytes nos valores das colunas

Se o modo SQL estrito não estiver habilitado e você atribuir um valor a uma coluna BLOB ou TEXT que exceda o comprimento máximo da coluna, o valor será truncado para caber e um aviso será gerado.

Comandos úteis:


verifique o modo estrito:SELECT @@global.sql_mode;

desative o modo estrito:

SET @@global.sql_mode='';

SET @@global.sql_mode='MYSQL40'

ou remove:sql-mode="STRICT_TRANS_TABLES,...

MOSTRAR COLUNAS DE mytable

SELECT max(namecount) AS virtualcolumn FROM mytable ORDER BY coluna virtual

http://dev.mysql.com /doc/refman/5.0/en/group-by-hidden-fields.html

http://dev.mysql .com/doc/refman/5.1/en/information-functions.html#function_last-insert-id last_insert_id()

obtém o PK da última linha inserida no thread atual max(pkcolname) obtém o último PK geral.

Nota:se a tabela estiver vazia max(pkcolname) retorna 1 mysql_insert_id() converte o tipo de retorno da função nativa da API MySQL C mysql_insert_id() para um tipo de long (chamado int em PHP).

Se sua coluna AUTO_INCREMENT tiver um tipo de coluna BIGINT, o valor retornado por mysql_insert_id() estará incorreto. Em vez disso, use a função SQL interna do MySQL LAST_INSERT_ID() em uma consulta SQL.

http://dev.mysql .com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

Apenas uma observação que quando você está tentando inserir dados em uma tabela e recebe o erro:
Unknown column ‘the first bit of data what you want to put into the table‘ in ‘field list’

usando algo como
INSERT INTO table (this, that) VALUES ($this, $that)

é porque você não tem apóstrofos em torno dos valores que está tentando colocar na tabela. Então você deve alterar seu código para:
INSERT INTO table (this, that) VALUES ('$this', '$that') 

lembrete de que `` são usados ​​para definir campos, bancos de dados ou tabelas MySQL, não valores;)

Perda de conexão com o servidor durante a consulta:

http://dev.mysql.com/doc/refman /5.1/en/gone-away.html

http://dev.mysql.com/doc /refman/5.1/en/packet-too-large.html

http://dev.mysql.com/doc/refman /5.0/en/server-parameters.html

http://dev.mysql.com/doc/refman /5.1/en/show-variables.html

http://dev.mysql.com/doc/refman /5.1/en/option-files.html

http://dev.mysql.com/doc/refman /5.1/en/error-log.html

Consultas de ajuste


http://www.artfulsoftware.com/infotree/queries.php?&bw =1313

Bem, isso deve ser o suficiente para ganhar o bônus, eu acho... Os frutos de muitas horas e muitos projetos com um ótimo grátis base de dados. Desenvolvo servidores de dados de aplicativos em plataformas Windows principalmente com MySQL. A pior bagunça que tive que arrumar foi

O pesadelo definitivo do banco de dados MySQL legado

Isso exigiu uma série de aplicativos para processar as tabelas em algo útil usando muitos dos truques mencionados aqui.

Se você achou isso incrivelmente útil, expresse seus agradecimentos votando.

Confira também meus outros artigos e white papers em:www.coastrd.com