Import von Daten mit google2piwik erheblich beschleunigen
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 😉
Gehen diese Änderungen dann auch Upstream?
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.
Bei Git kann man die Repos klonen und individuell weiterentwickeln…
@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.
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 😉