Was ich in KW 36 gelernt habe…

Persönliche Verbesserung ist wichtig (Kaizen-Prinzip). Gerade als Software-Entwickler sollten wir ständig nach Möglichkeiten suchen, wie wir unsere Arbeit noch besser und effektiver gestalten können.

Um hierüber künftig einen besseren Überblick zu haben werde ich jede Woche versuchen, eine kurze Zusammenfassung zu geben:

  1. Welche Bücher ich gelesen habe / bzw. lese (Fach und Fiktion)
  2. Welche Technologien gerade in meinem Fokus sind
  3. Welche Experimente interessant waren

Einerseits um die Dinge für mich transparent zu machen, und natürlich findet vielleicht der Eine oder Andere eine interessante Anregung, was als nächstes zu tun wäre.

KW36

Ich habe gelesen:

Meine anfängliche Begeisterung hat sich ein wenig gelegt, das Buch ist in Ordnung aber gerade in den späteren Kapiteln ist es teilweise schwer, den roten Faden zu erkennen.
Zusammengefasst kann man sagen, das Buch hat prinzipiell zwei wichtige Themen die angesprochen werden.
Einerseits die Wichtigkeit von Unternehmenskultur um auf dem Markt zu bestehen – gerade bei WordPress (komplett verteilte Entwicklung, keine festen Iterationen, keine festen Release Zyklen) braucht man die richtigen Menschen um “den Job zu machen”.
Der zweite wichtige Punkt des Buches ist, wie kann man einem solchen Umfeld ein Team führen? Die Erkenntnis ist nicht bahnbrechend – “Räume Hindernisse beiseite, löse Probleme und ansonsten geh aus dem Weg”.

Der erste Teil des Buches ist interessant, die Kurve flacht aber gegen Ende hin stark ab. Insgesamt hat es das Buch nicht auf meine Hitlist geschafft.

SQL – Optimierung

SQL Optimierung war ein Thema in dieser Woche.

Wichtige Tools hierfür:

MySQL – Explain

Vor jedem MySQL Befehl kann ein “EXPLAIN” gesetzt werden, was MySQL veranlasst, den ExecutionPlan ausgeben. Es kann sehr einfach nachvollzogen werden, was passiert und wo optimiert werden kann.

Nehmen wir als Beispiel einfach folgendes SQL-Skript.

create table person (id int, name varchar(256), email varchar(256), primary key(id)) engine = INNODB;
create table address (id int, street  varchar(60), zip varchar(5), city varchar(60), person_id int, primary key (id), foreign key(person_id) references person(id)) engine = INNODB;
insert into person (id, name, email) value (1, 'Hans', 'hans@test.de');
insert into person (id, name, email) value (2, 'Gerd', 'gerd@test.de');
insert into address (id, street, zip, city, person_id) values (1, 'test-straße', '80801','muenchen',1);
insert into address (id, street, zip, city, person_id) values (2, 'db-straße', '80802','muenchen',2);

Direkt danach setzen wir ein einfaches SELECT-Statement ab.

EXPLAIN SELECT * FROM PERSON WHERE ID = 1

Das Explain sieht so aus:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE person ALL NULL NULL NULL NULL 2 NULL

Interessant herbei ist die Spalte type weil wir hier sehen, dass ein FULL_TABLE_SCAN gemacht wird  (alle Datensätze werden durchsucht).

Machen wir ein weiteres Statement:

explain select * from person join address on person.id = address.person_id where person.id = 1

Das Ergebnis sieht so aus:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE person const PRIMARY PRIMARY 4 const 1 NULL
1 SIMPLE address ref ADDRESS_PERSON_IDX ADDRESS_PERSON_IDX 5 const 1 NULL

Das sieht soweit sehr gut aus, die Indizes werden verwendet, es findet kein FULL_TABLE_SCAN statt.

explain select * from person join address on person.id = address.person_id where address.zip = '80801'

Hier sieht der Execution-Plan schon ein wenig anders aus.

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE address ALL ADDRESS_PERSON_IDX NULL NULL NULL 2 Using where
1 SIMPLE person ALL PRIMARY NULL NULL NULL 3 Using where; Using join buffer (Block Nested Loop)

Wir durchsuchen unsere Datensätze nach Daten die nicht indiziert sind. Das Einzige was MySQL bleibt ist der gefürchtete FULL_TABLE_SCAN, also ein systematisches Durchsuchen aller Datensätze.

In der Spalte ‘possible_keys’ listet MySQL alle Schlüssel auf, die potentiell möglich sind. In der Spalte ‘key’ werden die tatsächlich verwendeten Keys aufgeführt. In diesem Fall gar keiner.

CREATE INDEX ADDRESS_ZIP_IDX ON ADDRESS(ZIP)

Lassen wir anschließend nochmals die gleiche Query laufen ergibt sich folgendes Bild:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a ref ADDRESS_PERSON_IDX,ADDRESS_ZIP_IDX ADDRESS_ZIP_IDX 8 const 1 Using index condition; Using where
1 SIMPLE person eq_ref PRIMARY PRIMARY 4 testdb.a.person_id 1 NULL

Wir sehen, der Index greift und die Suche wurde massiv beschleunigt.

Es kann übrigens sehr viele Gründe geben, warum MySQL einen Index nicht verwendet.
Beispielsweise folgende Query, die auf den ersten Blick ganz ähnlich der vorigen aussieht.

explain select *  from person join address a on person.id = a.person_id where a.zip = 80801

Der Execution-Plan sieht folgendermaßen aus. Man sieht den gefürchteten FULL_TABLE_SCAN, da der Index nicht verwendet wird. Das Problem ist das WHERE-Kriterium verwendet einen anderen Datentypen als der im Index angegebene (80801 statt ‘80801’). Das Ergebnis der Query ist dasselbe, der Datensatz wird gefunden, die Performance ist aber sehr viel schlechter.

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a ALL ADDRESS_PERSON_IDX,ADDRESS_ZIP_IDX NULL NULL NULL 2 Using where
1 SIMPLE person ALL PRIMARY NULL NULL NULL 2 Using where; Using join buffer (Block Nested Loop)

Zugegeben, das Beispiel ist trivial aber ich komme nicht allzu oft in den Genuss, eine SQL Query zu optimieren (dafür gibts doch Hibernate).

Auf so einfache Art und Weise lässt sich aber oft erstaunlich viel aus einer Query herausholen, gerade wenn EXPLAIN zugibt, einen FULL_TABLE_SCAN zu machen.

 

 

 

Effective Trainings & Consulting - Martin Dilger



Hat Ihnen dieser Blog-Eintrag gefallen? Ich stelle in diesem Blog Informationen über Tools, Frameworks und Werkzeuge zur Verfügung, die mich produktiver machen. Vielleicht kann ich auch Ihnen helfen, produktiver zu werden.


Ich unterstütze Sie als freier Mitarbeiter bei der Entwicklung von Software-Projekten, Agiler Arbeit sowie Schulungen / Fortbildungen.


Jeden Tag ein bisschen produktiver - ab heute