Vollständige Version anzeigen : MySQL Optimierung
Stefan Krohmer
07-23-2007, 07:54 PM
Guten Abend,
ich habe zur Zeit ein kleines Sorgenkind, das ich ein wenig tunen will. Es
ist ein Fujitsu Siemens Primergy RX200S3-110DE mit 2 GB RAM. Auf ihm läuft
MySQL 4.1, darin nur eine Datenbank (außer "mysql"), die auch gar keine
allzu großen Einträge enthält (ok, ist sehr subjektiv, aber das soll
vermutlich auch jetzt gar nicht das Problem sein). Ich habe mit Datenbank,
Rechner, Webserver und Netzwerk ein paar unangenehme Sachen erlebt und will
das ganze mal Stück für Stück durchputzen. Es läuft noch eine eigene
Applikation darauf sowie Apache/PHP, sonst nichts zusätzliches als das, was
Windows 2003 Server von Haus aus mitbringt. Soviel zur Vorgeschichte.
Ich habe mehrfach gelesen, dass die MySQL Auslieferungskonfiguration
irgendwie lauffähig ist, aber bei weitem nicht optimal. Inwiefern das
zutrifft, kann ich nicht beurteilen, kann mir aber denken, dass man da noch
einiges schrauben kann, je nach Konstellation HW/SW. Ich erwarte deshalb
auch sicher keine Musterlösung und kann mir aus den vielen Infos im Netz
mangels Erfahrung auch nicht sofort das wesentliche heraussaugen, sondern
möchte mal vorsichtig anfragen, was eure Erfahrungen sind, an welchen
Schrauben in der MySQL Konfiguration denn am ehesten zu drehen ist. Ich
habe nicht viel Versuchsspielraum, das ganze läuft in einer
Produktivumgebung und ich kann die Datenbank nur sporadisch neu starten,
aber nicht einfach so wie ich gerade Lust habe. Daher würde ich mich
freuen, wenn Ihr mir ein paar erste Tipps hättet, wo ich denn die
wahrscheinlichsten Erfolge verzeichnen könnte. Schrauben gibt's ja
leider/zum Glück genügend, an denen ich drehen könnte, aber ich will das
schon gezielt angehen.
Besten Dank, selbstverständlich auch für reine Links, wo ich weiter
nachlesen kann (MySQL Doku habe ich schon in Arbeit ;-))!
Gruß, Stefan
Christian Kirsch
07-23-2007, 08:10 PM
Bevor Du MySQL "optimieren" willst: gibt es dafür einen Grund? Läuft die
Datenbank zu langsam? Wenn ja: Hast Du in ihren Slow-Query-Log geguckt?
Wenn nein - warum willst Du dann irgendwas optimieren? Aus Deinem
Posting ging ja leider nichts faktisches hervor, nichtmal zur Größe der DB.
Axel Schwenke
07-23-2007, 08:48 PM
Stefan Krohmer <usenet*skrohmer.de> wrote:
> ich habe zur Zeit ein kleines Sorgenkind, das ich ein wenig tunen will. Es
> ist ein Fujitsu Siemens Primergy RX200S3-110DE mit 2 GB RAM. Auf ihm läuft
> MySQL 4.1, darin nur eine Datenbank (außer "mysql"), die auch gar keine
> allzu großen Einträge enthält (ok, ist sehr subjektiv, aber das soll
> vermutlich auch jetzt gar nicht das Problem sein). Ich habe mit Datenbank,
> Rechner, Webserver und Netzwerk ein paar unangenehme Sachen erlebt und will
> das ganze mal Stück für Stück durchputzen. Es läuft noch eine eigene
> Applikation darauf sowie Apache/PHP, sonst nichts zusätzliches als das, was
> Windows 2003 Server von Haus aus mitbringt.
Du läßt ein MySQL *produktiv* auf einem Windows laufen? Damit stehst du
ziemlich allein auf weiter Flur. Gibts dafür einen *guten* Grund?
<bla>
> Daher würde ich mich
> freuen, wenn Ihr mir ein paar erste Tipps hättet
....
> Besten Dank, selbstverständlich auch für reine Links, wo ich weiter
> nachlesen kann (MySQL Doku habe ich schon in Arbeit ;-))!
Das Kapitel zur Optimierung im Handbuch ist Pflicht. Allgemeines Wissen
über Performancetuning sowieso. Und was ein Index ist, solltest du auch
wissen. Mehr kann man mangels Details erst mal nicht sagen.
XL
Stefan Krohmer
07-23-2007, 08:49 PM
Hallo Christian,
Danke für die Nachfrage!
> Bevor Du MySQL "optimieren" willst: gibt es dafür einen Grund? Läuft
> die Datenbank zu langsam?
Nach meinem Eindruck frisst sie für das, was sie leisten soll, recht viel
Systemressourcen. Ich kann es gerade nicht genau beziffern, die genauen
Daten liegen am Arbeitsplatz, aber ich bekomme von max. 5 Clients nahezu
gleichzeitig einmal in der Sekunde Abfragen, wobei nur eine davon aus
max. 5 Tabellen einige zig Datensätze liest, und es ist keine Join-
Abfrage dabei, nur Selects. Es ist für mich etwas schwierig, das jetzt zu
beschreiben und auch zu berechnen. Die Datenbank enthält knapp 30
Tabellen, die verschiedene Objekte beschreiben, welche in C++ als Klassen
angelegt sind. Von diesen Objekten werden meistens max. 10 Stück gelesen.
Wenn zusätzlich noch eine Webserver Abfrage kommt, die aus ein paar der
Tabellen ca. 100 Objekte liest, kommt es sogar gelegentlich vor, dass der
Webserver die PHP Seite cancelt, weil sie länger als 30 Sekunden aufbaut
(normalerweise 2 Sekunden, wenn sonst keine Abfragen laufen). Die
längsten Einträge in den Tabellen enthalten deutlich weniger als 1000
Bytes, und es sind max. 2000 Einträge in einer Tabelle. Das hat mich zu
der Annahme geführt, dass da doch sicher noch was zu verbessern ist
(außer am Datenbankdesign, bei dem sich der Ersteller auf jeden Fall was
gedacht hat).
> Wenn ja: Hast Du in ihren Slow-Query-Log
> geguckt?
Nein, kannte das bisher nur vom Hörensagen, ich bin mit der Situation in
eine Problematik reingeraten, in die ich mich nun quasi an der Front
einarbeiten muss. Was würde mir denn das Log nützen? Ich werde mich wohl
mal diesbzgl. schlau machen.
> Wenn nein - warum willst Du dann irgendwas optimieren? Aus Deinem
> Posting ging ja leider nichts faktisches hervor, nichtmal zur Größe
> der DB.
Ich hoffe, ich konnte ein paar Fakten liefern (ist für mich grad echt ein
schwieriges Kapitel, muss mich da erst durchbeißen, aber der Sprung ins
kalte Wasser hat schon oft das Schwimmen gelehrt ;-)). Ich habe bewusst
nach einer groben Marschrichtung gefragt, weil es mir derzeit schwer
fällt, genauere Angaben zu machen und weil ich es nicht für reell halte,
ein Patentrezept vorgelegt zu bekommen, das geht IMHO nicht. Wenn
natürlich jemand sagt: "Den Parameter X musst du auf jeden Fall auf 2048
stellen", ist mir das auch recht, aber ein "Schau dir mal Y und Z an, die
sind meistens viel zu groß voreingestellt" hilft auf jeden Fall.
Vielleicht geht das ja so in etwa. Danke für eure Bemühungen!
Gruß, Stefan
Christian Kirsch
07-24-2007, 08:09 AM
Am 23.07.2007 21:49 schrieb Stefan Krohmer:
>
> Nach meinem Eindruck frisst sie für das, was sie leisten soll, recht viel
> Systemressourcen. Ich kann es gerade nicht genau beziffern, die genauen
> Daten liegen am Arbeitsplatz, aber ich bekomme von max. 5 Clients nahezu
> gleichzeitig einmal in der Sekunde Abfragen, wobei nur eine davon aus
> max. 5 Tabellen einige zig Datensätze liest, und es ist keine Join-
> Abfrage dabei, nur Selects.
Das alles hört sich eher nach "wenig" an.
> Es ist für mich etwas schwierig, das jetzt zu
> beschreiben und auch zu berechnen. Die Datenbank enthält knapp 30
> Tabellen, die verschiedene Objekte beschreiben, welche in C++ als Klassen
> angelegt sind.
Und dass es nicht MySQL sondern dein OR-Mapper (oder was immer) ist,
der die Ressourcen vertilgt, kann nicht sein? Was benutzt Du -
Hibernate? Oder bildest Du selbst brav alle Relationen in Klassen?
> Von diesen Objekten werden meistens max. 10 Stück gelesen.
Keine Vererbung? Keine "has a"-Beziehungen? Du kannst also sicher
sein, dass Deine 10 Objekte nicht jedes noch 10 weitere anziehen?
> Wenn zusätzlich noch eine Webserver Abfrage kommt, die aus ein paar der
> Tabellen ca. 100 Objekte liest, kommt es sogar gelegentlich vor, dass der
> Webserver die PHP Seite cancelt, weil sie länger als 30 Sekunden aufbaut
> (normalerweise 2 Sekunden, wenn sonst keine Abfragen laufen). Die
> längsten Einträge in den Tabellen enthalten deutlich weniger als 1000
> Bytes, und es sind max. 2000 Einträge in einer Tabelle.
Guck' Dir mal (wie Axel schon sagte) das MySQL-Handbuch
(dev.mysql.com/doc) an, dort den Abschnitt über Optimierung. Schalte
das Logging ein und guck' Dir an, welche Queries bei MySQL ankommen
(wer generiert die - wenn das eine OR-Abstraktionsschicht ist, lohnt
sich ein genauer Blick auf das, was da passiert).
Schick die Queries durch EXPLAIN (EXPLAIN SELECT ...) und guck' Dir
die Ausgabe an. Wenn da Full Table Scans auftauchen statt
Indexzugriffen, hast Du ein Problem.
Daniel Fischer
07-24-2007, 08:59 AM
Christian Kirsch!
> Schick die Queries durch EXPLAIN (EXPLAIN SELECT ...) und guck' Dir
> die Ausgabe an. Wenn da Full Table Scans auftauchen statt
> Indexzugriffen, hast Du ein Problem.
Wobei man die full table scans mit --log-queries-not-using-indexes auch
ins slow query log bekommt.
Gruß
Daniel
Andreas Kretschmer
07-24-2007, 09:08 AM
begin Daniel Fischer schrieb:
> Christian Kirsch!
>
>> Schick die Queries durch EXPLAIN (EXPLAIN SELECT ...) und guck' Dir
>> die Ausgabe an. Wenn da Full Table Scans auftauchen statt
>> Indexzugriffen, hast Du ein Problem.
>
> Wobei man die full table scans mit --log-queries-not-using-indexes auch
> ins slow query log bekommt.
.... und nicht jeder full table scan per se schlecht ist.
end
Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de
Sven Paulus
07-24-2007, 01:53 PM
Andreas Kretschmer <akretschmer*spamfence.net> wrote:
>>> Schick die Queries durch EXPLAIN (EXPLAIN SELECT ...) und guck' Dir
>>> die Ausgabe an. Wenn da Full Table Scans auftauchen statt
>>> Indexzugriffen, hast Du ein Problem.
>> Wobei man die full table scans mit --log-queries-not-using-indexes auch
>> ins slow query log bekommt.
> ... und nicht jeder full table scan per se schlecht ist.
Was genau der wunde Punkt bei dieser Logging-Option ist.
Ich haette da gerne nur Queries drin, die eigentlich - von ihrer Struktur -
von Indizes profitieren koennten und nicht einfach alle, bei denen keine
herangezogen werden.
Dass ein
SELECT foo FROM bar
keinen Index benutzen kann, weiss ich auch so, das muss mir nicht mein Log
vollrauschen.
Lustigerweise taucht obiger Query nicht im slow-log auf, wenn die
entsprechende Tabelle nur eine Zeile Inhalt hat.
Christian Kirsch
07-24-2007, 02:31 PM
Am 24.07.2007 14:53 schrieb Sven Paulus:
> Dass ein
> SELECT foo FROM bar
> keinen Index benutzen kann, weiss ich auch so, das muss mir nicht mein Log
> vollrauschen.
>
> Lustigerweise taucht obiger Query nicht im slow-log auf, wenn die
> entsprechende Tabelle nur eine Zeile Inhalt hat.
>
Dann ist die Abfrage vermutlich auch nicht "slow" ;-)
--
Christian
Andreas Kretschmer
07-24-2007, 02:43 PM
begin Sven Paulus schrieb:
> Andreas Kretschmer <akretschmer*spamfence.net> wrote:
>>>> Schick die Queries durch EXPLAIN (EXPLAIN SELECT ...) und guck' Dir
>>>> die Ausgabe an. Wenn da Full Table Scans auftauchen statt
>>>> Indexzugriffen, hast Du ein Problem.
>>> Wobei man die full table scans mit --log-queries-not-using-indexes auch
>>> ins slow query log bekommt.
>> ... und nicht jeder full table scan per se schlecht ist.
>
> Was genau der wunde Punkt bei dieser Logging-Option ist.
>
> Ich haette da gerne nur Queries drin, die eigentlich - von ihrer Struktur -
> von Indizes profitieren koennten und nicht einfach alle, bei denen keine
> herangezogen werden.
>
> Dass ein
> SELECT foo FROM bar
> keinen Index benutzen kann, weiss ich auch so, das muss mir nicht mein Log
> vollrauschen.
Selbst wenn foo eine Spalte id hat, auf der ein Index liegt, und ich
noch ein 'where id=1' an die Frage klatsche, kann ein full table scan
noch immer sinnvoller im Sinne von schneller sein als ein index scan.
(warum, steht schön beschrieben in der ix 7/07 Seite 134ff)
Soll es dann ins Log?
>
> Lustigerweise taucht obiger Query nicht im slow-log auf, wenn die
> entsprechende Tabelle nur eine Zeile Inhalt hat.
Weniger lustig ist, daß MySQL wenig darüber im Explain vermittelt, warum
es einen Plan wählt. Da steht (nach meinem Wissen zumindest) nix über
vermutete Kosten einer Abfrage, und EXPLAIN ANALYSE mit realen Kosten
gibt es IIRC auch nicht. Oder bin ich da nicht Up-to-date?
end
Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de
Daniel Fischer
07-24-2007, 03:19 PM
Sven Paulus!
> Dass ein
> SELECT foo FROM bar
> keinen Index benutzen kann, weiss ich auch so, das muss mir nicht mein Log
> vollrauschen.
Oh, kann es nicht? :-)
mysql> create table bar (foo int);
Query OK, 0 rows affected (0.01 sec)
mysql> insert into bar values (1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> explain extended select foo from bar;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | bar | ALL | NULL | NULL | NULL | NULL | 3 | |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> alter table bar add index (foo);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> explain extended select foo from bar;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | bar | index | NULL | foo | 5 | NULL | 3 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set, 1 warning (0.00 sec)
Gruß
Daniel
Andreas Kretschmer
07-24-2007, 03:23 PM
begin Daniel Fischer schrieb:
> Sven Paulus!
>
>> Dass ein
>> SELECT foo FROM bar
>> keinen Index benutzen kann, weiss ich auch so, das muss mir nicht mein Log
>> vollrauschen.
>
> Oh, kann es nicht? :-)
>
>
> mysql> create table bar (foo int);
> Query OK, 0 rows affected (0.01 sec)
>
>
> mysql> explain extended select foo from bar;
> +----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
> | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
> +----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
> | 1 | SIMPLE | bar | index | NULL | foo | 5 | NULL | 3 | Using index |
> +----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
> 1 row in set, 1 warning (0.00 sec)
An dieser Stelle könntest Du nun die table auch löschen und nur den
Index behalten...
SCNR ;-)
end
Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de
Daniel Fischer
07-24-2007, 03:45 PM
Andreas Kretschmer!
> An dieser Stelle könntest Du nun die table auch löschen und nur den
> Index behalten...
Bei der Beispieltabelle ist das langweilig, aber bei einer mit mehr
Spalten, bei der aber der Index auf die eine interessante im Speicher
gehalten wird, kann das schon eine Menge ausmachen :-)
Gruß
Daniel
Stefan Krohmer
07-24-2007, 05:09 PM
Hallo,
besten Dank mal für eure Infos bzgl. Slow Query Log, Explain, usw. Ich
werde mich in dieser Richtung mal betätigen und vor allem das MySQL
Tutorial gezielt durchgraben. Tut mir leid, dass ich grad keine näheren
Angaben machen kann, die aus eurer Sicht hilfreich wären. Bin, was die DB,
deren Struktur und die C++ Objekte angeht, kaum mit der Sache verwickelt,
hab's aber wie auch immer grad am Hals und versuche mich durchzubeißen.
Aber man wächst ja mit seinen Aufgaben :-)...
Gruß, Stefan
Andreas Kretschmer
07-24-2007, 07:06 PM
begin Daniel Fischer <spam*erinye.com> wrote:
> Andreas Kretschmer!
>> An dieser Stelle könntest Du nun die table auch löschen und nur den
>> Index behalten...
> Bei der Beispieltabelle ist das langweilig, aber bei einer mit mehr
> Spalten, bei der aber der Index auf die eine interessante im Speicher
> gehalten wird, kann das schon eine Menge ausmachen :-)
Ja. Da mag MySQL einen Vorteil gegenüber PG haben, das kann das IMHO
so nicht.
end
Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)
Axel Schwenke
07-24-2007, 08:52 PM
Sven Paulus <sven*karlsruhe.org> wrote:
> Andreas Kretschmer <akretschmer*spamfence.net> wrote:
>>> Wobei man die full table scans mit --log-queries-not-using-indexes auch
>>> ins slow query log bekommt.
>
> Was genau der wunde Punkt bei dieser Logging-Option ist.
>
> Ich haette da gerne nur Queries drin, die eigentlich - von ihrer Struktur -
> von Indizes profitieren koennten und nicht einfach alle, bei denen keine
> herangezogen werden.
Das geht mit den normalen Einstellmöglichkeiten nicht. Aber bei Peter
Zaitzevs MySQLPerformanceBlog gibts einen Patch, der ein paar weitere
Möglichkeiten nachrüstet:
- Ausführungszeit und slow-Limit in Mikrosekunden.
- ein Limit für untersuchte Zeilen. Damit kann man Queries
unterdrücken, die nur wenige Zeilen scannen.
Ansonsten kannst du einen Kommentar in die Queries schreiben, bei
denen eine Optimierung nicht sinnvoll ist und sie später aus dem
Slow-Log rausfiltern.
XL
vBulletin v3.6.7, Copyright ©2000-2010, Jelsoft Enterprises Ltd.