Schlagwort-Archive: MySQL

Google Analytics Alternative: Piwik

Google Analytics ist ohne Zweifel ein großartiges Tool, um seine Webzugriffe zu analysieren. Welche Seiten wurden am häufigsten besucht, wie hoch ist die Absprungrate, mit welchen Suchbegriffen landen Benutzer auf meiner Seite, bringt es etwas Tags zu verwenden, welche Begriffe bringen am meisten Besucher und viele weitere Fragen können mittels Webanalyse beantwortet werden. Den Traffic umfangreich zu analysieren, Schlüsse daraus zu ziehen und die eigene Webseite/Blog weiter zu optimieren, ist bestimmt ein guter Ansatz. So habe ich bspw. mit diesem Blog zu Beginn der Analyse 40 Besucher am Tag gehabt, mittlerweile liege ich bei 140 Besuchern durchschnittlich – neulich waren es sogar 220 am Tag.

Das Problem mit Google Analytics

Der Landesbeauftragte für Datenschutz von Schleswig-Holstein bringt es wie folgt auf den Punkt:

Derzeit ist die Nutzung des kostenlosen Google Analytics Services durch Webseitenanbieter unzulässig. Google muss dessen Konfiguration so ändern, dass die Betroffenen ihr Recht auf Widerspruch, Information und Auskunft sowie Löschung der Daten wirksam wahrnehmen können. Für den rechtswidrigen Einsatz des Dienstes haften die Webseitenbetreiber.

Verwendet man Google Analytics überträgt man die IP-Adresse des Besuchers an einen Dritten (Google), was auch dann nicht im Einklang mit dem Datenschutz ist, wenn man im Impressum den Besucher darauf hinweist, dass man Google Analytics verwendet. Der Besucher muss zustimmen oder dem Webseitenbetreiber muss eine gesetzliche Ermächtigung vorliegen, damit die personenbezogenen Daten (IP-Adresse) übermittelt werden dürfen. Andernfalls läuft man Gefahr von Abmahnungen..
Zwar wurde die zentrale Forderung der Datenschutz-Behörden durch Googles Nachbesserung durch die _anonymizeIp() Funktion erfüllt (wenn man denn Google den Glauben schenken kann, dass diese Funktion tatsächlich die IP anonymisiert), es bleibt jedoch die Frage der datenschutzrechtlich zulässigen Widerspruchsmöglichkeit erhalten – sprich: Es ist mir als Nutzer nicht möglich zu sagen, dass Google meine Daten nicht sammeln soll.

Ein weiteres Problem bei der Verwendung von Google Analytics ist, dass viele Benutzer Skripts von Google in ihrem Browser sperren, so dass keine Daten erfasst werden.

Google hat den Ruf einer Datenkrake und man muss sich fragen, warum Google solch ein aufwändiges Produkt wie Google Analytics kostenlos anbietet – sicherlich nicht aus reinem Gutmenschentum, sondern um intern die Daten weiter zu verarbeiten und Zugriffe zu tracken, die sich außerhalb des Google Universums abspielen.

Piwik – Eine kostenlose open source Alternative

Piwik Logo

Piwik hat den entscheidenden Vorteil, dass alle Daten bei einem selber bleiben. Die Installation ist einfach und lediglich PHP und MySQL ist notwendig. Mittlerweile bietet Piwik (Version 1.0) nahezu alle Möglichkeiten, die man von Google Analytics kennt.

Als ich im Dezember 2009 (Piwik 0.5.1) anfing, die open source Alternative zu nutzen, habe ich noch etliche Features vermisst. Die Entwicklung von Piwik war allerdings so rasant, dass ich bei dieser Software blieb. Ich bin gespannt, wohin sie sich noch entwickeln wird.

Mein Rat: Ausprobieren!

MySQL: UPDATE auf mehreren Tabellen und Subqueries

Wer sich mal ein bißchen näher mit SQL beschäftigt, wird über die Ausdrucksmächtigkeit und Performance erstaunt sein. SQL kann eben doch mehr als simple SELECT-Anweisungen zu verarbeiten.

Mal ein Beispiel, was man alles mit UPDATE-Anweisungen machen kann:

Wir haben folgende Tabellen

1. Team

  • Teamid
  • Teamname
  • AnzahlMitglieder

2. User

  • Userid
  • Username
  • Teamid

Nun wollen wir das noch leere Feld Team.AnzahlMitglieder aus der Tabelle User berechnen. Naiver Ansatz ist wahrscheinlich folgendes UPDATE-Statement, wenn man sich vorher klar macht, dass man Subqueries verwenden kann, um Werte zu setzen:
[code lang=’sql‘]UPDATE Team
SET
AnzahlMitglieder =
(SELECT COUNT(*)
FROM User
WHERE User.Teamid = Team.Teamid )[/code]

Problem an dieser Abfrage ist allerdings, dass für jede Zeile, die aktualisiert werden soll, das Subquery ausgeführt wird. Bei kleineren Datenmengen macht das nichts, wenn es allerdings Millionen an Datensätze sind, braucht das UPDATE ewig.

Wie könnte die Lösung aussehen? Richtig, man führt den Subquery nur 1x für alle Teams aus und selektiert den jeweiligen Eintrag dann für das entsprechende Team:
[code lang=’sql‘]UPDATE
Team,
(SELECT teamid,
COUNT(*) as anzahl,
FROM User) AS usersub
SET
Team.AnzahlMitglieder = usersub.anzahl
WHERE
Team.Teamid = usersub.teamid)[/code]

Performancevergleich: Enzelne SQL-Statements vs. MySQL LOAD DATA INFILE vs. Prepared Statements

Performance: Einzelne SQL-Statements

Was macht das Programm?

  1. Aus einer großen XML-Datei werden per SAXParser Datensätze eingelesen. Insgesamt gibt es 1.109.270 „Datensätze“ in der XML-Datei.
  2. Aus jedem Datensatz werden 2 SQL-Queries erzeugt: Ein REPLACE-Statement zum Einfügen/Aktualsieren von Stammdaten und ein INSERT-Statement zum Einfügen von Bewegungsdaten

Es werden also kontinuierlich SQL-Statements abgesetzt.

Laufzeit des Programms

41 Minuten und 36 Sekunden

Performance: Generierung der CSV-Datei & LOAD DATA INFILE

Was macht das Programm?

  1. (identisch mit vorherigem Programm:) Aus einer großen XML-Datei werden per SAXParser Datensätze eingelesen. Insgesamt gibt es 1.109.270 „Datensätze“ in der XML-Datei.
  2. Aus jedem Datensatz werden 2 CSV-Dateien um einen Datensatz erweitert. Die erste Datei enthält die Daten für die Stammdaten-Tabelle, die zweite Datei enthält die Bewegungsdaten.
  3. Zwei LOAD DATA INFILE Befehle zum Einlesen der CSV-Dateien.

Das Programm erzeugt also zuerst 2 Dateien und greift erst zum Schluss auf die Datenbank zu.

Laufzeit des Programms

30 Minuten und 9 Sekunden

Performance: Nur LOAD DATA INFILE

Wenn wir annehmen, dass die 2 CSV-Dateien schon vorhanden sind und nur noch die LOAD DATA INFILE-Befehle ausgeführt werden müssen, so sind die immerhin 2.218.540 Datensätze innerhalb von

2 Minuten und 23 Sekunden

importiert.

Performance: Prepared Statements

Prepared Statements sollten nicht nur aus sicherheitsrelevanten Überlegungen eingesetzt werden, sondern bringen – richtig implementiert – auch einen Performance-Vorteil. Dieser Vorteil lässt sich so erklären, dass 1x das SQL-Statement mit „?“ als Platzhalter an das DBMS übertragen wird und danach werden für jeden Datensatz nur noch die Parameter übertragen, die in die entsprechenden Platzhalter durch das DBMS eingefügt werden. Es fallen also weniger zu übertragene Daten an, aber vor allem können die Daten so übertragen und verarbeitet werden, dass sie nicht mehr durch das DB-System interpretiert bzw. konvertiert werden müssen. Das Ergebnis kann sich sehen lassen:

Das Programm ist identisch mit dem Programm, welches kontinuierlich, einzelne SQL-Statements absetzt. Allerdings ist es so programmiert, dass es die Performance-Vorteile der Prepared Statements nutzt.

Laufzeit des Programms

28 Minuten und 30 Sekunden

Fazit

Bei so großen Datenmengen, die sequentiell eingelesen werden, kommt es auf die richtige Wahl der Methode an:

Vorteile Prepared Statements:

  • sind einfach zu implementieren
  • sind  im Performance-Vergleich noch ein Stück weit schneller als CSV-Dateien zu erstellen und per LOAD DATA INFILE einzulesen

Nachteile Prepared Statements:

  • die Datenbank wird über die gesamte Zeit stark belastet

Vorteile Generierung von CSV & LOAD DATA INFILE:

  • die Datenbank wird nur für kurze Zeit beansprucht
  • die CSV-Datei kann nach dem Generieren gespeichert bleiben und zu Diagnosezwecke bzw. wiederholten Datenimport verwendet werden

Nachteile Generierung von CSV & LOAD DATA INFILE:

  • kompliziertere Implementierung
  • zusätzlicher Festplattenverbrauch durch CSV-Dateien
  • geringfügig langsamer als Prepared Statements