Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Versteckte Funktionen von MySQL

Da du ein Kopfgeld ausgesetzt hast, teile ich meine hart erkämpften Geheimnisse...

Im Allgemeinen erforderten alle SQLs, die ich heute optimiert habe, die Verwendung von Unterabfragen. Da ich aus der Welt der Oracle-Datenbanken komme, funktionierten Dinge, die ich für selbstverständlich hielt, mit MySQL nicht so. Und meine Lektüre zum MySQL-Tuning lässt mich zu dem Schluss kommen, dass MySQL in Bezug auf die Optimierung von Abfragen hinter Oracle zurückliegt.

Während die einfachen Abfragen, die für die meisten B2C-Anwendungen erforderlich sind, für MySQL gut funktionieren können, scheinen die meisten Abfragen des aggregierten Berichtstyps, die für Intelligence Reporting benötigt werden, einiges an Planung und Neuorganisation der SQL-Abfragen zu erfordern, damit MySQL sie schneller ausführen kann.

Verwaltung:

max_connections ist die Anzahl der gleichzeitigen Verbindungen. Der Standardwert ist 100 Verbindungen (151 seit 5.0) - sehr klein.

Hinweis:

Verbindungen nehmen Speicher in Anspruch und Ihr Betriebssystem kann möglicherweise nicht viele Verbindungen verarbeiten.

MySQL-Binärdateien für Linux/x86 ermöglichen Ihnen bis zu 4096 gleichzeitige Verbindungen, aber selbst kompilierte Binärdateien haben oft weniger Grenzen.

Stellen Sie table_cache so ein, dass es mit der Anzahl Ihrer offenen Tabellen und gleichzeitigen Verbindungen übereinstimmt. Beobachten Sie den open_tables-Wert und wenn er schnell wächst, müssen Sie ihn vergrößern.

Hinweis:

Die 2 vorherigen Parameter erfordern möglicherweise viele offene Dateien. 20+max_connections+table_cache*2 ist eine gute Schätzung für das, was Sie brauchen. MySQL unter Linux hat eine open_file_limit-Option, setzen Sie diese Grenze.

Wenn Sie komplexe Abfragen haben, sind sort_buffer_size und tmp_table_size wahrscheinlich sehr wichtig. Die Werte hängen von der Komplexität der Abfrage und den verfügbaren Ressourcen ab, aber 4 MB bzw. 32 MB sind empfohlene Ausgangspunkte.

Hinweis:Dies sind "pro Verbindung"-Werte, darunter read_buffer_size, read_rnd_buffer_size und einige andere, was bedeutet, dass dieser Wert möglicherweise für jede Verbindung benötigt wird. Berücksichtigen Sie daher Ihre Auslastung und die verfügbaren Ressourcen, wenn Sie diese Parameter festlegen. Zum Beispiel wird sort_buffer_size nur zugewiesen, wenn MySQL eine Sortierung durchführen muss. Hinweis:Achten Sie darauf, dass Ihnen nicht der Speicherplatz ausgeht.

Wenn Sie viele Verbindungen hergestellt haben (d. h. eine Website ohne dauerhafte Verbindungen), können Sie die Leistung verbessern, indem Sie thread_cache_size auf einen Wert ungleich Null setzen. 16 ist ein guter Wert für den Anfang. Erhöhen Sie den Wert, bis Ihre threads_created nicht mehr sehr schnell wachsen.

PRIMÄRSCHLÜSSEL:

Es kann nur eine AUTO_INCREMENT-Spalte pro Tabelle geben, sie muss indiziert sein und darf keinen DEFAULT-Wert haben

KEY ist normalerweise ein Synonym für INDEX. Das Schlüsselattribut PRIMARY KEY kann auch nur als KEY angegeben werden, wenn es in einer Spaltendefinition angegeben wird. Dies wurde aus Gründen der Kompatibilität mit anderen Datenbanksystemen implementiert.

Ein PRIMARY KEY ist ein eindeutiger Index, bei dem alle Schlüsselspalten als NOT NULL

definiert werden müssen

Wenn ein PRIMARY KEY- oder UNIQUE-Index nur aus einer Spalte vom Typ Integer besteht, können Sie in SELECT-Anweisungen auch auf die Spalte als "_rowid" verweisen.

In MySQL lautet der Name eines PRIMARY KEY PRIMARY

Derzeit unterstützen nur Tabellen von InnoDB (v5.1?) Fremdschlüssel.

Normalerweise erstellen Sie alle Indizes, die Sie benötigen, wenn Sie Tabellen erstellen. Jede Spalte, die als PRIMARY KEY, KEY, UNIQUE oder INDEX deklariert ist, wird indiziert.

NULL bedeutet „keinen Wert haben“. Sie können nicht auf NULL testen Verwenden Sie die arithmetischen Vergleichsoperatoren wie =, . Verwenden Sie stattdessen die Operatoren IS NULL und IS NOT NULL:

NO_AUTO_VALUE_ON_ZERO unterdrückt die automatische Inkrementierung für 0, sodass nur NULL die nächste Sequenznummer generiert. Dieser Modus kann nützlich sein, wenn 0 in der AUTO_INCREMENT-Spalte einer Tabelle gespeichert wurde. (Das Speichern von 0 ist übrigens keine empfohlene Vorgehensweise.)

So ändern Sie den Wert des AUTO_INCREMENT-Zählers, der für neue Zeilen verwendet werden soll:

ALTER TABLE mytable AUTO_INCREMENT = value; 

oderSET INSERT_ID =value;

Sofern nicht anders angegeben, beginnt der Wert mit:1000000 oder geben Sie ihn so an:

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

ZEITSTEMPEL:

Werte für TIMESTAMP-Spalten werden zum Speichern von der aktuellen Zeitzone in UTC und zum Abrufen von UTC in die aktuelle Zeitzone konvertiert.

http://dev.mysql.com/doc/refman/5.1 /en/timestamp.html Für eine TIMESTAMP-Spalte in einer Tabelle können Sie den aktuellen Zeitstempel als Standardwert und als Wert für die automatische Aktualisierung zuweisen.

Eine Sache, auf die Sie achten sollten, wenn Sie einen dieser Typen in einer WHERE-Klausel verwenden, ist es am besten, WHERE datecolumn =FROM_UNIXTIME(1057941242) und notWHERE UNIX_TIMESTAMP(datecolumn) =1057941242 zu tun. Wenn Sie letzteres tun, wird ein Index darauf nicht ausgenutzt Spalte.

http://dev.mysql.com /doc/refman/5.1/en/date-and-time-functions.html

 UNIX_TIMESTAMP() 
 FROM_UNIXTIME() 
 UTC_DATE()
 UTC_TIME()
 UTC_TIMESTAMP()

Wenn Sie in MySQL eine Datumszeit in einen Unix-Zeitstempel konvertieren:
Und dann 24 Stunden dazuzählen:
Und dann zurück in eine Datumszeit konvertieren, geht auf magische Weise eine Stunde verloren!

Hier ist, was passiert. Beim Konvertieren des Unix-Zeitstempels zurück in eine Datumszeit wird die Zeitzone berücksichtigt, und es passiert einfach so, dass wir zwischen dem 28. und 29. Oktober 2006 die Sommerzeit verlassen haben und eine Stunde verloren haben.

Ab MySQL 4.1.3 geben die Funktionen CURRENT_TIMESTAMP(), CURRENT_TIME(), CURRENT_DATE() und FROM_UNIXTIME() Werte in der aktuellen Zeitzone der Verbindung zurück , die als Wert der Systemvariablen time_zone verfügbar ist. Außerdem nimmt UNIX_TIMESTAMP() an, dass sein Argument ein datetime-Wert in der aktuellen Zeitzone ist.

Die aktuelle Zeitzoneneinstellung wirkt sich nicht auf Werte aus, die von Funktionen wie UTC_TIMESTAMP() oder Werten in DATE-, TIME- oder DATETIME-Spalten angezeigt werden.

HINWEIS:NUR BEI AKTUALISIERUNG NUR aktualisiert DateTime, wenn ein Feld geändert wird Wenn ein UPDATE dazu führt, dass keine Felder geändert werden, wird DateTime NICHT aktualisiert!

Außerdem ist der erste TIMESTAMP standardmäßig immer AUTOUPDATE, auch wenn er nicht angegeben ist

Wenn ich mit Datumsangaben arbeite, konvertiere ich fast immer zu Julian Date, da Datenmathematik dann eine einfache Sache des Addierens oder Subtrahierens von ganzen Zahlen ist, und Sekunden seit Mitternacht aus dem gleichen Grund. Es kommt selten vor, dass ich eine Zeitauflösung mit einer feineren Granularität als Sekunden benötige.

Beide können als 4-Byte-Ganzzahl gespeichert werden, und wenn der Platz wirklich knapp ist, können sie in die UNIX-Zeit (Sekunden seit der Epoche 1.1.1970) als vorzeichenlose Ganzzahl kombiniert werden, die bis etwa 2106 gut sein wird als:

' Sekunden in 24 Stunden =86400

' Signed Integer max val =2.147.483.647 - kann 68 Jahre Sekunden speichern

' Unsigned Integer max val =4.294.967.295 - kann 136 Jahre Sekunden speichern

Binärprotokoll:

MySQL 4.1 führte ein Binärprotokoll ein, das es ermöglicht, Nicht-String-Datenwerte im nativen Format ohne Konvertierung in das und aus dem String-Format zu senden und zurückzugeben. (Sehr nützlich)

Abgesehen davon ist mysql_real_query() schneller als mysql_query(), da es strlen() nicht aufruft, um mit der Anweisungszeichenfolge zu arbeiten.

http://dev.mysql.com/tech-resources /articles/4.1/prepared-statements.html Das Binärprotokoll unterstützt serverseitig vorbereitete Anweisungen und ermöglicht die Übertragung von Datenwerten im nativen Format. Das Binärprotokoll wurde während der früheren Versionen von MySQL 4.1 ziemlich überarbeitet.

Sie können das Makro IS_NUM() verwenden, um zu testen, ob ein Feld einen numerischen Typ hat. Übergeben Sie den Typwert an IS_NUM() und es ergibt TRUE, wenn das Feld numerisch ist:

Zu beachten ist, dass binäre Daten KÖNNEN innerhalb einer regulären Abfrage gesendet werden, wenn Sie es maskieren und sich daran erinnern, dass MySQL nur benötigt Dieser Backslash und das Anführungszeichen werden maskiert. Das ist also eine wirklich einfache Möglichkeit, kürzere binäre Zeichenfolgen wie zum Beispiel verschlüsselte/gesalzene Passwörter einzufügen.

Master-Server:

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

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

GEWÄHREN SIE REPLIKATIONS-SLAVE AUF . an slave_user IDENTIFIED BY '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

Binäre Protokolldatei muss lauten:

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

Sie können alle binären Protokolldateien mit der Anweisung RESET MASTER oder eine Teilmenge davon mit PURGE MASTER

löschen

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

Normalisierung:

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

UDF-Funktionen

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

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

Datentypen:

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/

Zu beachten ist, dass mySQL bei einer gemischten Tabelle mit CHAR und VARCHAR die CHAR in VARCHAR ändert

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

MySQL stellt Datumsangaben immer mit dem ersten Jahr dar, in Übereinstimmung mit den Standard-SQL- und ISO-8601-Spezifikationen

Sonstiges:

Das Deaktivieren einiger MySQl-Funktionen führt zu kleineren Datendateien und schnellerem Zugriff. Zum Beispiel:

--datadir gibt das Datenverzeichnis an und

--skip-innodb schaltet die inno-Option aus und spart Ihnen 10-20 Millionen

Mehr hierhttp://dev.mysql.com/tech -resources/articles/mysql-c-api.html

Laden Sie Kapitel 7 herunter – kostenlos

InnoDB ist transaktional, aber damit verbunden ist ein Performance-Overhead. Ich habe festgestellt, dass MyISAM-Tabellen für 90 % meiner Projekte ausreichen. Nicht transaktionssichere Tabellen (MyISAM) haben mehrere eigene Vorteile, die alle auftreten, weil:

es gibt keinen Transaktionsaufwand:

Viel schneller

Geringerer Speicherplatzbedarf

Weniger Arbeitsspeicher erforderlich, um Aktualisierungen durchzuführen

Jede MyISAM-Tabelle wird in drei Dateien auf der Festplatte gespeichert. Die Namen der Dateien beginnen mit dem Tabellennamen und haben eine Erweiterung, um den Dateityp anzugeben. Eine .frm-Datei speichert das Tabellenformat. Die Datendatei hat die Erweiterung .MYD (MYData). Die Indexdatei hat die Erweiterung .MYI (MYIndex).

Diese Dateien können intakt an einen Speicherort kopiert werden, ohne die Backup-Funktion des MySQL-Administrators zu verwenden, die zeitaufwändig ist (wie auch die Wiederherstellung)

Der Trick besteht darin, eine Kopie dieser Dateien zu erstellen und dann die Tabelle zu löschen. Wenn Sie die Dateien zurücklegen, wird MySQl sie erkennen und die Tabellenverfolgung aktualisieren.

Wenn Sie sichern/wiederherstellen müssen,

Das Wiederherstellen einer Sicherung oder das Importieren aus einer vorhandenen Speicherauszugsdatei kann abhängig von der Anzahl der Indizes und Primärschlüssel, die Sie für jede Tabelle haben, lange dauern. Sie können diesen Vorgang erheblich beschleunigen, indem Sie Ihre ursprüngliche Dump-Datei ändern, indem Sie sie mit dem Folgenden umgeben:

SET AUTOCOMMIT = 0;
SET FOREIGN_KEY_CHECKS=0;

.. your dump file ..

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

Um die Geschwindigkeit des Neuladens erheblich zu erhöhen, fügen Sie den SQL-Befehl SET AUTOCOMMIT =0; am Anfang der Dump-Datei und fügen Sie das COMMIT hinzu; Befehl bis zum Ende.

Standardmäßig ist Autocommit aktiviert, was bedeutet, dass jeder einzelne Einfügungsbefehl in der Dump-Datei als separate Transaktion behandelt und auf die Festplatte geschrieben wird, bevor die nächste gestartet wird. Wenn Sie diese Befehle nicht hinzufügen, kann das Neuladen einer großen Datenbank in InnoDB viele Stunden dauern...

Die maximale Größe einer Zeile in einer MySQL-Tabelle beträgt 65.535 Byte

Die effektive maximale Länge eines VARCHAR in MySQL 5.0.3 und höher =maximale Zeilengröße (65.535 Byte)

VARCHAR-Werte werden beim Speichern nicht aufgefüllt. Nachfolgende Leerzeichen werden gemäß Standard-SQL beibehalten, wenn Werte gespeichert und abgerufen werden.

CHAR- und VARCHAR-Werte in MySQL werden ohne Rücksicht auf nachgestellte Leerzeichen verglichen.

Die Verwendung von CHAR beschleunigt Ihren Zugriff nur, wenn der gesamte Datensatz eine feste Größe hat. Das heißt, wenn Sie irgendein Objekt mit variabler Größe verwenden, können Sie genauso gut alle mit variabler Größe machen. Sie gewinnen keine Geschwindigkeit, wenn Sie ein CHAR in einer Tabelle verwenden, die auch ein VARCHAR enthält.

Das VARCHAR-Limit von 255 Zeichen wurde ab MySQL 5.0.3

auf 65535 Zeichen angehoben

Volltextsuchen werden nur für MyISAM-Tabellen unterstützt.

http://dev.mysql.com/doc/refman /5.0/de/volltextsuche.html

BLOB-Spalten haben keinen Zeichensatz, und Sortierung und Vergleich basieren auf den numerischen Werten der Bytes in Spaltenwerten

Wenn der strikte SQL-Modus nicht aktiviert ist und Sie einer BLOB- oder TEXT-Spalte einen Wert zuweisen, der die maximale Länge der Spalte überschreitet, wird der Wert gekürzt, damit er passt, und es wird eine Warnung generiert.

Nützliche Befehle:

strengen Modus prüfen:SELECT @@global.sql_mode;

strikten Modus deaktivieren:

SET @@global.sql_mode='';

SET @@global.sql_mode='MYSQL40'

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

SPALTEN VON mytable ANZEIGEN

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()

ruft den PK der letzten in den aktuellen Thread eingefügten Zeile ab max(pkcolname) ruft den letzten PK insgesamt ab.

Hinweis:Wenn die Tabelle leer ist, gibt max(pkcolname) 1 zurück. mysql_insert_id() konvertiert den Rückgabetyp der nativen MySQL-C-API-Funktion mysql_insert_id() in einen Long-Typ (in PHP int genannt).

Wenn Ihre AUTO_INCREMENT-Spalte den Spaltentyp BIGINT hat, ist der von mysql_insert_id() zurückgegebene Wert falsch. Verwenden Sie stattdessen die interne MySQL-SQL-Funktion LAST_INSERT_ID() in einer SQL-Abfrage.

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

Nur eine Anmerkung:Wenn Sie versuchen, Daten in eine Tabelle einzufügen, erhalten Sie den Fehler:

Unknown column ‘the first bit of data what you want to put into the table‘ in ‘field list’

mit so etwas wie

INSERT INTO table (this, that) VALUES ($this, $that)

Das liegt daran, dass Sie keine Apostrophe um die Werte haben, die Sie in die Tabelle einfügen möchten. Sie sollten also Ihren Code ändern in:

INSERT INTO table (this, that) VALUES ('$this', '$that') 

Erinnerung daran, dass `` verwendet werden, um MySQL-Felder, Datenbanken oder Tabellen zu definieren, nicht Werte;)

Verlorene Verbindung zum Server während der Abfrage:

http://dev.mysql.com/doc/refman /5.1/en/weggegangen.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

Optimierungsabfragen

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

Nun, das sollte ausreichen, um den Bonus zu verdienen, denke ich ... Die Früchte vieler Stunden und vieler Projekte mit einem großartigen gratis Datenbank. Ich entwickle Anwendungsdatenserver auf Windows-Plattformen hauptsächlich mit MySQL. Das schlimmste Durcheinander, das ich beseitigen musste, war

Der ultimative MySQL-Legacy-Datenbank-Albtraum

Dies erforderte eine Reihe von Anwendungen, um die Tabellen mit vielen der hier erwähnten Tricks zu etwas Nützlichem zu verarbeiten.

Wenn Sie dies erstaunlich hilfreich fanden, drücken Sie Ihren Dank aus, indem Sie es positiv bewerten.

Sehen Sie sich auch meine anderen Artikel und Whitepaper an:www.coastrd.com