Dal momento che hai offerto una taglia, condividerò i miei segreti conquistati a fatica ...
In generale, tutti gli SQL che ho messo a punto oggi richiedono l'utilizzo di sottoquery. Essendo arrivato dal mondo dei database Oracle, le cose che davo per scontate non funzionavano allo stesso modo con MySQL. E la mia lettura sull'ottimizzazione di MySQL mi fa concludere che MySQL è dietro Oracle in termini di ottimizzazione delle query.
Sebbene le semplici query richieste per la maggior parte delle applicazioni B2C possano funzionare bene per MySQL, la maggior parte del tipo di query di reporting aggregato necessario per Intelligence Reporting sembra richiedere un bel po 'di pianificazione e riorganizzazione delle query SQL per guidare MySQL ad eseguirle più velocemente.
Amministrazione:
max_connections
è il numero di connessioni simultanee. Il valore predefinito è 100 connessioni (151 dalla 5.0) - molto piccolo.
Nota:
le connessioni richiedono memoria e il tuo sistema operativo potrebbe non essere in grado di gestire molte connessioni.
I binari MySQL per Linux / x86 consentono di avere fino a 4096 connessioni simultanee, ma i binari autocompilati spesso hanno meno limiti.
Imposta table_cache in modo che corrisponda al numero delle tue tabelle aperte e delle connessioni simultanee. Guarda il valore di open_tables e se sta crescendo rapidamente dovrai aumentare le sue dimensioni.
Nota:
I 2 parametri precedenti potrebbero richiedere molti file aperti. 20 + max_connections + table_cache * 2 è una buona stima per ciò di cui hai bisogno. MySQL su Linux ha un'opzione open_file_limit, imposta questo limite.
Se hai query complesse, è probabile che sort_buffer_size e tmp_table_size siano molto importanti. I valori dipenderanno dalla complessità della query e dalle risorse disponibili, ma rispettivamente 4 MB e 32 MB sono punti di partenza consigliati.
Nota: questi sono valori "per connessione", tra read_buffer_size, read_rnd_buffer_size e alcuni altri, il che significa che questo valore potrebbe essere necessario per ogni connessione. Quindi, considera il tuo carico e la risorsa disponibile quando imposti questi parametri. Ad esempio, sort_buffer_size viene allocato solo se MySQL deve eseguire un ordinamento. Nota: fare attenzione a non esaurire la memoria.
Se sono state stabilite molte connessioni (ad esempio un sito web senza connessioni persistenti) potresti migliorare le prestazioni impostando thread_cache_size su un valore diverso da zero. 16 è un buon valore per iniziare. Aumenta il valore finché il tuo thread_created non cresce molto rapidamente.
CHIAVE PRIMARIA:
Può esserci una sola colonna AUTO_INCREMENT per tabella, deve essere indicizzata e non può avere un valore DEFAULT
KEY è normalmente un sinonimo di INDICE. L'attributo chiave PRIMARY KEY può anche essere specificato come KEY quando fornito in una definizione di colonna. Questo è stato implementato per compatibilità con altri sistemi di database.
UNA CHIAVE PRIMARIA è un indice univoco in cui tutte le colonne chiave devono essere definite come NOT NULL
Se un indice PRIMARY KEY o UNIQUE è costituito da una sola colonna che ha un tipo intero, è anche possibile fare riferimento alla colonna come "_rowid" nelle istruzioni SELECT.
In MySQL, il nome di una PRIMARY KEY è PRIMARY
Attualmente, solo le tabelle InnoDB (v5.1?) Supportano le chiavi esterne.
Di solito, crei tutti gli indici di cui hai bisogno quando crei le tabelle. Qualsiasi colonna dichiarata come PRIMARY KEY, KEY, UNIQUE o INDEX verrà indicizzata.
NULL significa "non avere un valore". Per verificare la presenza di NULL, non è possibile utilizzare gli operatori di confronto aritmetico come =, <o <>. Utilizza invece gli operatori IS NULL e IS NOT NULL:
NO_AUTO_VALUE_ON_ZERO sopprime l'incremento automatico per 0 in modo che solo NULL generi il numero di sequenza successivo. Questa modalità può essere utile se 0 è stato memorizzato nella colonna AUTO_INCREMENT di una tabella. (La memorizzazione di 0 non è una pratica consigliata, a proposito.)
Per modificare il valore del contatore AUTO_INCREMENT da utilizzare per le nuove righe:
ALTER TABLE mytable AUTO_INCREMENT = value;
o SET INSERT_ID = valore;
Se non diversamente specificato, il valore inizierà con: 1000000 o specificarlo così:
...) ENGINE = MyISAM DEFAULT CHARSET = latin1 AUTO_INCREMENT = 1
Timestamp: da
I valori per le colonne TIMESTAMP vengono convertiti dal fuso orario corrente a UTC per l'archiviazione e da UTC al fuso orario corrente per il recupero.
http://dev.mysql.com/doc/refman/5.1/en/timestamp.html
Per una colonna TIMESTAMP in una tabella, puoi assegnare il timestamp corrente come valore predefinito e il valore di aggiornamento automatico.
una cosa a cui prestare attenzione quando si utilizza uno di questi tipi in una clausola WHERE, è meglio fare WHERE datecolumn = FROM_UNIXTIME (1057941242) e non WHERE UNIX_TIMESTAMP (datecolumn) = 1057941242. facendo quest'ultimo non si trarrà vantaggio da un indice su quella colonna.
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 converti un datetime in unix timestamp in MySQL:
e poi aggiungi 24 ore ad esso:
e poi lo converti di nuovo in un datetime, perde magicamente un'ora!
Ecco cosa sta succedendo. Quando si converte di nuovo il timestamp unix in un datetime, viene preso in considerazione il fuso orario e accade solo che tra il 28 e il 29 ottobre 2006 siamo usciti dall'ora legale e abbiamo perso un'ora.
A partire da MySQL 4.1.3, le funzioni CURRENT_TIMESTAMP (), CURRENT_TIME (), CURRENT_DATE () e FROM_UNIXTIME () restituiscono valori nel fuso orario corrente della connessione , che è disponibile come valore della variabile di sistema time_zone. Inoltre, UNIX_TIMESTAMP () presuppone che il suo argomento sia un valore datetime nel fuso orario corrente.
L'impostazione del fuso orario corrente non influisce sui valori visualizzati da funzioni come UTC_TIMESTAMP () o sui valori nelle colonne DATE, TIME o DATETIME.
NOTA: SOLO SU AGGIORNAMENTO aggiorna il DateTime se un campo viene modificato Se un UPDATE risulta in nessun campo modificato, il DateTime NON viene aggiornato!
Inoltre, il primo TIMESTAMP è sempre AUTOUPDATE per impostazione predefinita anche se non specificato
Quando lavoro con le date, mi convinco quasi sempre a Julian Date perché la matematica dei dati è quindi una semplice questione di aggiungere o sottrarre numeri interi e secondi da mezzanotte per lo stesso motivo. È raro che abbia bisogno di una risoluzione temporale con una granularità più fine dei secondi.
Entrambi possono essere memorizzati come un numero intero di 4 byte, e se lo spazio è veramente stretto può essere combinato nel tempo UNIX (secondi dall'epoca 1/1/1970) come un numero intero senza segno che sarà valido fino a circa 2106 come:
'secondi in 24 ore = 86400
'Valori interi con segno massimo = 2.147.483.647 - può contenere 68 anni di secondi
"Valori interi non firmati max = 4.294.967.295 - può contenere 136 anni di secondi
Protocollo binario:
MySQL 4.1 ha introdotto un protocollo binario che consente di inviare e restituire valori di dati non di stringa in formato nativo senza conversione da e verso il formato stringa. (Molto utile)
A parte, mysql_real_query () è più veloce di mysql_query () perché non chiama strlen () per operare sulla stringa dell'istruzione.
http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html
Il protocollo binario supporta istruzioni preparate lato server e consente la trasmissione di valori di dati in formato nativo. Il protocollo binario ha subito un bel po 'di revisione durante le versioni precedenti di MySQL 4.1.
È possibile utilizzare la macro IS_NUM () per verificare se un campo ha un tipo numerico. Passa il valore del tipo a IS_NUM () e restituisce TRUE se il campo è numerico:
Una cosa da notare è che i dati binari POSSONO essere inviati all'interno di una normale query se esegui l'escape e ricordi che MySQL richiede solo la barra rovesciata e il carattere di virgolette. Quindi questo è un modo davvero semplice per INSERIRE stringhe binarie più brevi come password crittografate / salate, ad esempio.
Server principale:
http://www.experts-exchange.com/Database/MySQL/Q_22967482.html
http://www.databasejournal.com/features/mysql/article.php/10897_3355201_2
CONCEDERE REPLICA SLAVE ON . a slave_user IDENTIFICATO DA "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
Il file di registro binario deve leggere:
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
È possibile eliminare tutti i file di registro binari con l'istruzione RESET MASTER o un sottoinsieme di essi con PURGE MASTER
--result-file = binlog.txt TrustedFriend-bin.000030
Normalizzazione:
http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html
Funzioni UDF
http://www.koders.com/cpp/fid10666379322B54AD41AEB0E4100D87C8CDDF1D8C.aspx
http://souptonuts.sourceforge.net/readme_mysql.htm
Tipi di dati:
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/
Una cosa da notare è che su una tabella mista con CHAR e VARCHAR, mySQL cambierà i CHAR in VARCHAR
RecNum integer_type UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (RecNum)
MySQL rappresenta sempre le date con l'anno prima, in conformità con le specifiche SQL standard e ISO 8601
Varie:
Disattivare alcune funzionalità di MySQl comporterà file di dati più piccoli e un accesso più rapido. Per esempio:
--datadir specificherà la directory dei dati e
--skip-innodb disattiverà l'opzione inno e ti farà risparmiare 10-20 milioni
Maggiori informazioni qui
http://dev.mysql.com/tech-resources/articles/mysql-c-api.html
Scarica il capitolo 7 - gratuito
InnoDB è transazionale ma comporta un sovraccarico di prestazioni. Ho trovato le tabelle MyISAM sufficienti per il 90% dei miei progetti. Le tabelle non sicure per le transazioni (MyISAM) hanno diversi vantaggi, che si verificano tutti perché:
non vi è alcun sovraccarico di transazione:
Più veloce
Minori requisiti di spazio su disco
Meno memoria richiesta per eseguire gli aggiornamenti
Ogni tabella MyISAM è archiviata su disco in tre file. I file hanno nomi che iniziano con il nome della tabella e hanno un'estensione per indicare il tipo di file. Un file .frm memorizza il formato della tabella. Il file di dati ha un'estensione .MYD (MYData). Il file indice ha un'estensione .MYI (MYIndex).
Questi file possono essere copiati in una posizione di archiviazione intatta senza utilizzare la funzione di backup degli amministratori di MySQL che richiede tempo (così come il ripristino)
Il trucco è fare una copia di questi file e poi SCARICARE la tabella. Quando rimetti i file, MySQl li riconoscerà e aggiornerà il monitoraggio della tabella.
Se è necessario eseguire il backup / ripristino,
Il ripristino di un backup o l'importazione da un file di dump esistente può richiedere molto tempo a seconda del numero di indici e chiavi primarie presenti su ciascuna tabella. È possibile accelerare notevolmente questo processo modificando il file di dump originale circondandolo con quanto segue:
SET AUTOCOMMIT = 0;
SET FOREIGN_KEY_CHECKS=0;
.. your dump file ..
SET FOREIGN_KEY_CHECKS = 1;
COMMIT;
SET AUTOCOMMIT = 1;
Per aumentare notevolmente la velocità di ricarica, aggiungere il comando SQL SET AUTOCOMMIT = 0; all'inizio del file dump e aggiungi il COMMIT; comando fino alla fine.
Per impostazione predefinita, autocommit è attivo, il che significa che ogni comando di inserimento nel file di dump verrà trattato come una transazione separata e scritto su disco prima dell'avvio di quello successivo. Se non aggiungi questi comandi, ricaricare un database di grandi dimensioni in InnoDB può richiedere molte ore ...
La dimensione massima di una riga in una tabella MySQL è 65.535 byte
La lunghezza massima effettiva di un VARCHAR in MySQL 5.0.3 e su = dimensione massima della riga (65.535 byte)
I valori VARCHAR non vengono riempiti quando vengono memorizzati. Gli spazi finali vengono conservati quando i valori vengono memorizzati e recuperati, in conformità con lo standard SQL.
I valori CHAR e VARCHAR in MySQL vengono confrontati senza considerare gli spazi finali.
L'utilizzo di CHAR accelera l'accesso solo se l'intero record è di dimensioni fisse. Cioè, se usi qualsiasi oggetto di dimensione variabile, potresti anche renderli tutti di dimensione variabile. Non si guadagna velocità utilizzando un CHAR in una tabella che contiene anche un VARCHAR.
Il limite VARCHAR di 255 caratteri è stato aumentato a 65535 caratteri a partire da MySQL 5.0.3
Le ricerche full-text sono supportate solo per le tabelle MyISAM.
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
Le colonne BLOB non hanno un set di caratteri e l'ordinamento e il confronto si basano sui valori numerici dei byte nei valori delle colonne
Se la modalità SQL rigorosa non è abilitata e si assegna un valore a una colonna BLOB o TEXT che supera la lunghezza massima della colonna, il valore viene troncato per adattarsi e viene generato un avviso.
Comandi utili:
controlla la modalità rigorosa: SELECT @@ global.sql_mode;
disattiva la modalità rigorosa:
SET @@ global.sql_mode = '';
SET @@ global.sql_mode = 'MYSQL40'
o rimuovi: sql-mode = "STRICT_TRANS_TABLES, ...
MOSTRA COLONNE DA mytable
SELEZIONA 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 ()
ti dà il PK dell'ultima riga inserita nel thread corrente max (pkcolname) ti fa l'ultimo PK in totale.
Nota: se la tabella è vuota, max (pkcolname) restituisce 1 mysql_insert_id () converte il tipo restituito della funzione API C MySQL nativa mysql_insert_id () in un tipo di long (denominato int in PHP).
Se la tua colonna AUTO_INCREMENT ha un tipo di colonna BIGINT, il valore restituito da mysql_insert_id () non sarà corretto. Utilizzare invece la funzione SQL MySQL interna LAST_INSERT_ID () in una query SQL.
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
Solo una nota che quando stai cercando di inserire dati in una tabella e ottieni l'errore:
Unknown column ‘the first bit of data what you want to put into the table‘ in ‘field list’
usando qualcosa di simile
INSERT INTO table (this, that) VALUES ($this, $that)
è perché non hai apostrofi sui valori che stai cercando di inserire nella tabella. Quindi dovresti cambiare il tuo codice in:
INSERT INTO table (this, that) VALUES ('$this', '$that')
ricorda che `` vengono utilizzati per definire campi, database o tabelle MySQL, non valori;)
Connessione al server persa durante la query:
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
Query di ottimizzazione
http://www.artfulsoftware.com/infotree/queries.php?&bw=1313
Beh, questo dovrebbe bastare per guadagnare il bonus penserei ... I frutti di tante ore e tanti progetti con un ottimo database gratuito . Sviluppo server dati applicativi su piattaforme Windows principalmente con MySQL. Il peggior pasticcio che ho dovuto sistemare è stato
L'incubo definitivo del database legacy MySQL
Ciò ha richiesto una serie di applicazioni per elaborare le tabelle in qualcosa di utile utilizzando molti dei trucchi menzionati qui.
Se lo hai trovato incredibilmente utile, esprimi i tuoi ringraziamenti votandolo.
Controlla anche i miei altri articoli e white paper su: www.coastrd.com