Já que você colocou uma recompensa, vou compartilhar meus segredos duramente conquistados ...
Em geral, todos os SQLs que ajustei hoje exigiam o uso de subconsultas. Tendo vindo do mundo do banco de dados Oracle, coisas que eu considerava certas não funcionavam da mesma forma com o MySQL. E minha leitura sobre o ajuste do MySQL me faz concluir que o MySQL está por trás do Oracle em termos de otimização de consultas.
Embora as consultas simples exigidas para a maioria dos aplicativos B2C possam funcionar bem para o MySQL, a maioria dos tipos de consultas de relatórios agregados necessários 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.
Nota:
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é 4096 conexões simultâneas, mas os binários auto-compilados 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.
Nota:
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 dependem 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 recursos disponíveis 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), você pode 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 um sinônimo para INDEX. O atributo de chave PRIMARY KEY também pode ser especificado apenas como KEY quando fornecido em uma definição de coluna. Isso foi implementado para compatibilidade com outros sistemas de banco de dados.
Uma PRIMARY KEY é um índice único onde todas as colunas-chave devem ser definidas como NOT NULL
Se um índice PRIMARY KEY ou UNIQUE consistir em apenas uma coluna que possui um tipo inteiro, você também pode se referir à coluna como "_rowid" nas instruções SELECT.
No MySQL, o nome de uma PRIMARY KEY é PRIMARY
Atualmente, apenas tabelas InnoDB (v5.1?) Suportam chaves estrangeiras.
Normalmente, você cria todos os índices de que precisa 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 usar os operadores de comparação aritmética, como =, <ou <>. Em vez disso, use os operadores IS NULL e IS NOT NULL:
NO_AUTO_VALUE_ON_ZERO suprime o incremento automático de 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;
ou SET INSERT_ID = valor;
A menos que especificado de outra forma, o valor começará com: 1000000 ou especifique-o assim:
...) ENGINE = MyISAM DEFAULT CHARSET = latin1 AUTO_INCREMENT = 1
TIMESTAMPS:
Os valores das colunas TIMESTAMP são convertidos do fuso horário atual em UTC para armazenamento e de UTC no 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 carimbo de data / hora atual como o valor padrão e o valor de atualização automática.
uma coisa a se observar ao usar um desses tipos em uma cláusula WHERE, é melhor fazer WHERE datecolumn = FROM_UNIXTIME (1057941242) e não WHERE UNIX_TIMESTAMP (datecolumn) = 1057941242. fazer o último não tirará proveito de um índice nessa 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 uma data e hora em um carimbo de data e hora Unix no MySQL:
E então adicionar 24 horas a ele:
E então convertê-lo de volta em uma data e hora, ele magicamente perde uma hora!
Aqui está o que está acontecendo. Ao converter o timestamp unix de volta para uma data e hora, 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: ON UPDATE atualiza SOMENTE o DateTime se um campo for alterado. Se um UPDATE resultar em nenhum campo sendo alterado, o DateTime NÃO é atualizado!
Além disso, o primeiro TIMESTAMP é sempre AUTOUPDATE por padrão, mesmo se não for especificado
Ao trabalhar com datas, quase sempre convoco para data juliana porque a matemática de dados é então uma simples questão de adicionar ou subtrair inteiros e segundos desde a meia-noite pelo mesmo motivo. É raro eu precisar de uma resolução de tempo de granularidade mais fina do que segundos.
Ambos podem ser armazenados como um número inteiro de 4 bytes e, se o espaço for realmente apertado, podem ser combinados no tempo UNIX (segundos desde a época 01/01/1970) como um número inteiro sem sinal que será bom até cerca de 2106 como:
's em 24 horas = 86400
'Número inteiro assinado val = 2.147.483.647 - pode conter 68 anos de segundos
'Inteiro sem sinal max val = 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 muitas 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 avalia como TRUE se o campo for numérico:
Uma coisa a notar é que os dados binários PODEM ser enviados dentro de uma consulta regular se você escapar dela e lembrar que o MySQL requer apenas que a barra invertida e o caractere de aspas sejam escapados. Essa é uma maneira realmente fácil de INSERIR strings binárias mais curtas, como senhas criptografadas / com Sal, 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
GRANT REPLICATION SLAVE ON . 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 conter:
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 se notar é que em uma tabela mista com CHAR e VARCHAR, mySQL mudará os CHARs para VARCHARs
RecNum integer_type UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (RecNum)
MySQL sempre representa as datas com o ano primeiro, de acordo com as especificações padrão SQL e ISO 8601
Diversos:
Tirar algumas funcionalidades do MySQL resultará em arquivos de dados menores e acesso mais rápido. Por exemplo:
--datadir irá especificar o diretório de dados e
--skip-innodb desligará a opção Inno e economizará 10-20M
Mais aqui
http://dev.mysql.com/tech-resources/articles/mysql-c-api.html
Baixe o capítulo 7 - grátis
O InnoDB é transacional, mas há uma sobrecarga de desempenho que vem com ele. Eu 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 as quais ocorrem porque:
não há sobrecarga de transação:
Muito mais rapido
Requisitos de menor espaço em disco
Menos memória necessária para realizar atualizações
Cada tabela MyISAM é armazenada em disco em três arquivos. Os arquivos têm nomes que começam com o nome da tabela e têm 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 possui uma extensão .MYI (MYIndex).
Esses arquivos podem ser copiados para um local de armazenamento intacto, sem o uso do recurso de backup de administradores do MySQL, que é demorado (assim como a restauração)
O truque é fazer uma cópia desses arquivos e então DROP a tabela. Quando você colocar os arquivos de volta, o MySQL irá reconhecê-los e atualizar o rastreamento da tabela.
Se você deve 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ê tem 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 todo e qualquer comando de inserção no arquivo de despejo será tratado como uma transação separada e gravada no disco antes que a próxima seja iniciada. Se você não adicionar esses comandos, recarregar um grande banco de dados 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 finais 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 levar em conta os espaços à direita.
O uso de CHAR só irá 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 tornar todos eles 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 têm conjunto de caracteres e a classificação e comparação são baseadas nos valores numéricos dos bytes nos valores da coluna
Se o modo SQL estrito não estiver ativado 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;
desligue o modo estrito:
SET @@ global.sql_mode = '';
SET @@ global.sql_mode = 'MYSQL40'
ou remova: sql-mode = "STRICT_TRANS_TABLES, ...
MOSTRAR COLUNAS DE mytable
SELECT max (namecount) AS virtualcolumn
FROM mytable ORDER BY virtualcolumn
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 MySQL C API nativa mysql_insert_id () em um tipo de long (nomeado int em PHP).
Se sua coluna AUTO_INCREMENT tem 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ê tenta inserir dados em uma tabela e obtém 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 inserir na tabela. Portanto, 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;)
Conexão perdida 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 banco de dados gratuito . Eu desenvolvo servidores de dados de aplicativos em plataformas Windows principalmente com MySQL. A pior bagunça que eu tive que resolver foi
O pior pesadelo do banco de dados legado MySQL
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.
Verifique também meus outros artigos e white papers em: www.coastrd.com