7 Reaktionen

Import von Daten mit google2piwik erheblich beschleunigen

Geschätzte Lesedauer:

Wie ich im vorherigen Artikel beschrieben habe, ist google2piwik ein nützliches Tool zum importieren von Daten aus Google Analytics in Piwik.

Leider ist das Importskript sehr langsam. Langsam sind dabei nicht vorwiegend die einzelnen Abfragen der Daten aus Analytics oder das Speichern in Piwik, sondern eine SQL UPDATE Anweisung am Ende des Skriptes.
Nach jedem erfolgreichen Durchlauf des Skriptes wird ein Counter aktualisiert. Hierfür wird die folgende Abfrage verwendet:

[pastacode lang=“sql“ message=“MySQL“ highlight=““ provider=“manual“]

UPDATE log_visit AS lv
LEFT JOIN (
SELECT  idvisit, COUNT(*) AS visit_actions
FROM
   log_link_visit_action
GROUP BY
   idvisit
) AS m ON
   m.idvisit = lv.idvisit
SET lv.visit_total_actions = m.visit_actions
WHERE visit_last_action_time >= ''
AND visit_last_action_time < = ''

[/pastacode]

<STARTZEIT> und <ENDZEIT> sind hierbei die eingestellten Werte aus der Konfiguration.

Bei uns brauchte hierbei das Aktualisieren des Counters für 7 Tage(!) zwischen 10 und 15 Minuten. Wenn man bedenkt, dass der Datenstamm aus 5 Jahren besteht, dann kann man sich vorstellen, dass dies keine akzeptable Dauer ist. Dabei lässt sich das gewünschte Ergebnis durch eine viel einfachere SQL Abfrage erreichen.

[pastacode lang=“sql“ message=“MySQL“ highlight=““ provider=“manual“]

UPDATE log_visit AS lv
SET lv.visit_total_actions = (
   SELECT COUNT(*)
   FROM
      log_link_visit_action as la
   WHERE la.idvisit = lv.idvisit
)
WHERE visit_last_action_time >= ''
AND visit_last_action_time < = ''

[/pastacode]

Mit dieser Variante beträgt die Laufzeit der Abfrage im Test gerade einmal 0,5 Sekunden.

Hier noch kurz die Erklärung wo die Anpassung erfolgen muss:
Die Anweisung steht in der sql.py Datei ziemlich am Ende:

[pastacode lang=“python“ message=“Python“ highlight=““ provider=“manual“]

def update_visit_actions(start_date, end_date):
    raw_sql = """UPDATE {LV} AS lv
                        LEFT JOIN (
                            SELECT  idvisit, COUNT(*) AS visit_actions
                            FROM
                                {LVA}
                            GROUP BY
                                idvisit
                        ) AS m ON
                            m.idvisit = lv.idvisit
                    SET lv.visit_total_actions = m.visit_actions
                    WHERE visit_last_action_time >= %s
                      AND visit_last_action_time < = %s
                """.format(LV = T_LOGV, LVA = T_LOGVA)
    cursor.execute(raw_sql, (start_date, end_date))

[/pastacode]

wir ändern dies also in

[pastacode lang=“python“ message=“Python“ highlight=““ provider=“manual“]

def update_visit_actions(start_date, end_date):
    raw_sql = """UPDATE {LV} AS lv
                        SET lv.visit_total_actions = (
                            SELECT COUNT(*)
                            FROM
                                {LVA} as la
                            WHERE
                                la.idvisit = lv.idvisit
                        )
                 WHERE visit_last_action_time >= %s
                      AND visit_last_action_time < = %s
                """.format(LV = T_LOGV, LVA = T_LOGVA)
    cursor.execute(raw_sql, (start_date, end_date))

[/pastacode]

So einfach kann Performancetuning sein 😉

Dieser Artikel wurde von Marius Burkard verfasst.

Marius Burkard ist Diplom-Wirtschaftsinformatiker und arbeitet seit 2006 als selbstständiger Software-Entwickler und Linux-Server-Administrator mit der Firma pixcept KG. Er ist unter anderem mitverantwortlich für die Projekte Was-lese-ich.de und ISPProtect.

5 Kommentare - bis jetzt!

Eigenen Kommentar verfassen
  1. Gast
    schrieb am :

    Gehen diese Änderungen dann auch Upstream?

  2. schrieb am :

    Nun ja, ich habe keinen Zugriff auf die Original-Quellen und auch keinen Kontakt zu den Developern und da sich am Projekt schon einige Zeit nichts getan hat, weiß ich nicht ob jemand diese Änderungen übernehmen würde.

    Die Änderungen aus dem anderen Artikel können auch nicht ohne Weiteres übernommen werden, da sie davon abhängig sind, dass auch der Code des Google „gdata“ Moduls geändert wird.

  3. schrieb am :

    Bei Git kann man die Repos klonen und individuell weiterentwickeln…

  4. schrieb am :

    @Christoph, natürlich kann man das. Macht haber wenig Sinn, wenn die Originale ebenfalls weiterentwickelt werden und es nur um einmalige Änderungen geht, die auch noch „Kreuzabhängigkeit“ (oder wie man das nennen soll) haben.

  5. schrieb am :

    Vielen Dank für Deinen Hinweis 🙂 🙂 🙂

    Ich hab noch eine kleine Ergänzung – da mein Import nach der beschriebenen Änderung nicht wirklich schneller war, hab ich Deinen SQL Code auch noch bei update_total_visit_actions verwendet. Jetzt ist’s zwar immernoch langsam, aber schon etwas schneller als vorher 😉

    def update_total_visit_actions():
        raw_sql = „““UPDATE {LV} AS lv
                            SET lv.visit_total_actions = (
                                SELECT COUNT(*)
                                FROM
                                    {LVA} as la
                                WHERE
                                    la.idvisit = lv.idvisit
                            )
                    „““.format(LV=T_LOGV, LVA=T_LOGVA)
        cursor.execute(raw_sql)

Und jetzt du! Deine Meinung?

Erforderliche Felder sind mit einem Asterisk (*) gekennzeichnet. Die E-Mail-Adresse wird nicht veröffentlicht.
  1. Nach Absenden des Kommentar-Formulars erfolgt eine Verarbeitung der von Ihnen eingegebenen personenbezogenen Daten durch den datenschutzrechtlich Verantwortlichen zum Zweck der Bearbeitung Ihrer Anfrage auf Grundlage Ihrer durch das Absenden des Formulars erteilten Einwilligung.
    Weitere Informationen