Messungen an Landing Pages

In diesem Artikel stelle ich die Auswertung der Messwerte an einer Landing Page vor.

Unser Testobjekt

Eigens zu Test- und Forschungszwecken haben wir eine kleine Landing Page vorbereitet. Sie zeigt Dr. Snider, der eine Wunderpille verkauft, die schlank macht. Die Landing Page gehört zur Klasse der Video-Landing Pages (mehr dazu im Artikel über Landing Pages und ist aufs wesentliche reduziert:

  • Überschrift
  • ein großflächiges Video
  • ein Button „für x US$ kaufen“, der nach einiger Zeit erscheint
  • das gesetzlich vorgeschriebene Impressum

Das Video haben wir eigens für diesen Test produzieren lassen und zeigt einen „Doktor“, der eine Wunder-Pille verkauft, die schlank macht. Wir haben uns bewusst für das Schlankheits-Thema entschieden, da allgemein bekannt ein großer Markt dafür existiert. Somit konnten wir recht günstigen, ungetargeteten Traffic dafür einkauen. Sollten Sie ein ernst gemeintes Thema bewerben wollen, das eine kleinere Zielgruppe anspricht, sollten Sie auf alle Fälle hochwertigeren Traffic benutzen.

Die Landing Page als Messinstrument

Neben der Conversion Rate Anzahl Käufer / Anzahl Besucher war es uns auch wichtig, AB-Tests durchzuführen. Konkret hat uns interessiert, wie hoch die Conversion Rate ist, wenn das Produkt 1€, 5€ oder 39€ kostet. Technisch haben wir das so realisiert, dass jedem Besucher eine zufällige Variante der Seite ausgeliefert wurde. Die Datenauswertung kann dann für alle Varianten getrennt erfolgen.

Was wir gemessen haben

Nach dem deutschen Datenschutz-Gesetz gelten für die Verarbeitung personenbezogener Daten besondere Regeln, die insbesondere mit Recht auf Auskunft, Recht auf Löschung, Korrektur und vielem mehr behaftet sind. Um diesen Aufwand zu sparen, ist es wichtig, das Prinzip der Datensparsamkeit bewusst anzuwenden. Anonymisiert man Daten ausrechend, sodass keine Rückschlüsse mehr auf die Person gezogen werden können, fallen diese nicht unter die strengen Regelungen der Personenbezogenen Daten. Das heißt konkret für Landing Pages: Keine Cookies, keine IP-Adressen, keine Verknüpfungen mit z.B. Facebook-Accounts oder Google-Accounts.

Pro Besucher wurde ein Datensatz angelegt, der folgendes misst:

  • Gewählte Variante (1€, 5€ oder 39€)
  • Zeitpunkt des Besuchs
  • Dauer des Besuchs
  • Zeitpunkt, an dem der Kaufen-Knopf geklickt wurde (oder 0 falls nicht geklickt)

Auswertung der Daten

Hier einige SQL-Anfragen:

  • SELECT COUNT( * ) FROM `Visitor`
    Wie viele Besucher gab es auf der Seite?
    21205
  • SELECT AVG( TimeToLive <>0 ) FROM `Visitor`
    Wie viele der Besucher haben das Video gestartet?
    0.7210 (72%)
  • SELECT AVG( TimeToLive >10 )
    FROM `Visitor`

    Wie viele der Besucher haben sich die Seite länger als 10 Sekunden angesehen?
    0.4208 (42%)
  • SELECT AVG( TimeToLive >35 ) FROM `Visitor`
    Wie viele der Besucher haben sich das Video zu Ende angesehen?
    0.1123 (11%)
  • SELECT Variante, (SELECT Preis FROM Variante WHERE Variante.ID = Variante) AS Preis, COUNT(*) FROM `Visitor` GROUP BY Variante
    Wie viele Besucher gab es je Variante?

    Variante Preis COUNT(*)
    1 1 6988
    2 5 6906
    3 39 7311
  • SELECT Variante, (SELECT Preis FROM Variante WHERE Variante.ID = Variante) AS Preis, SUM(TimeCallToActionClicked<>0) AS Converters, AVG(TimeCallToActionClicked<>0) AS ConversionRate FROM `Visitor` GROUP BY Variante
    Welche Variante hatte welche Conversions?

    Variante Preis Converters ConversionRate
    1 1 4 0.0006
    2 5 4 0.0006
    3 39 2 0.0003
  • SELECT SUM(Preis * (TimeCallToActionClicked<>0)) FROM Variante, Visitor WHERE Variante.ID = Visitor.Variante
    Wie hoch sind die potenziellen Einnahmen? (Preis*Conversion)
    102 €

Fazit

Video-Landing Pages werden beachtet. 11% der Besucher haben sich das Video zu Ende angesehen. Die Conversion Rate lag unter einer Promille, was zum einen mit unserem unseriösen Test-Angebot zusammen hängen kann, zum anderen war der Traffic nicht gerade der teuerste. Beachtet man jedoch die vorhandenen Conversions, muss man sagen, dass man mit 102€ potenziellen Umsatz für die 21.000 gekauften Besucher von Adfly, die lediglich 8 € gekostet haben, jede Menge erreicht hat.

Überlegen Sie jetzt auch, mehr Kunden durch Landing Pages zu gewinnen? Wir von Launix helfen gern weiter.

MySQL-Datenbank-Anfragen optimieren: Zu jeder Query passt ein MultiIndex

Neulich führte ich eine Query aus, die mehr als 9 Sekunden rechnete. Die Query bestand aus einem Join zweier Tabellen: Eine Liste von Items und einem Zeitverlauf je Item. Vom Schema sah das ungefähr so aus:

Item(ShopID, SubID, Title)
ItemPrice(ShopID, SubID, Price, Timestamp)

Die Query sah ungefähr so aus:
SELECT Title, (SELECT Price FROM ItemPrice p WHERE i.ShopID = p.ShopID AND i.SubID = p.SubID ORDER BY Timestamp DESC LIMIT 1) AS Price FROM Item i

Auf gutdeutsch also: Liste alle Items mit ihrem neuesten Preis auf.

Die Krux mit den Joins?

Hat man etwa 9.000 Items und ca. 11.000 Preisänderungen, würde die Query sofort lahm werden. Doch woran liegt das?

Zum einen gibt es hier eine Nested Query. Es gibt zwar eine allgemeine Methode, beliebige Sub-Queries in Joins umzuwandeln (Paper von Thomas Neumann auf der BTW15, Hamburg), allerdings kann diese Methode nicht mit der ORDER BY und dem LIMIT-Klausel umgehen. Der Ausführungsplan der Query ist also klar: Zuerst wird die Item-Tabelle gescannt und für jede ihrer Zeilen wird die Sub-Query ausgeführt. Grundessenz einer Query-Optimierung hier ist also, dass die Subquery möglichst ohne Zeitaufwand stattfindet (am besten Lookup-Index).

Das nächste Problem ist die unklare Schlüssel-Situation, denn hier bilden zwei Schlüssel den Primär-Index. Ein Index müsste also beide Schlüssel enthalten.

Der MultiIndex

Es gibt grundsätzlich zwei Arten von Indizes: Den Hash-Index und den BTree. Der Hash-Index ist eine Hash-Table, aus der man idealerweise mit einem Aufwand O(1) Items herauspicken kann, deren Zugriffs-Schlüssel man kennt. Der BTree hingegen ist eine Art sortierter Listen-Baum. Der BTree kann weit mehr als der Hash-Index: Items mit einem exakten Key finden, Items, deren Key zwischen zwei Werten liegt oder einfach die Items in sortierter Reihenfolge auslesen.

Weitet man einen Index auf mehrere Dimensionen aus, spielt sich etwas interessantes ab: Beim Hash-Index kann man nur noch Werte abfragen, bei denen man die Werte aller Zugriffs-Schlüssel kennt. Der BTree hingegen hat folgende Features:

  • Ist mein Index 4-dimensional, ich kenne aber nur die ersten 2 Schlüssel-Werte, kann ich trotzdem einen Lookup durchführen
  • Ist mein Index 4-dimensional, ich kenne aber nur die ersten 2 Schlüssel-Werte, kann ich auf dem dritten Schlüssel Bereichs-Anfragen (von-bis) durchführen
  • Ist mein Index 4-dimensional, ich kenne aber nur die ersten 2 Schlüssel-Werte, kann ich den dritten Schlüssel sortiert auslesen

Technisch gesehen ist der multidimensionale BTree also eine Liste, die nach den Schlüsseln sortiert ist. Der Aufwand für eine BTree-Anfrage ist O(log(n)).

Effiziente Verwendung des MultiIndex

Jeder Index verbraucht Speicher in der Datenbank. Deshalb sollte man sparsam mit Indizes umgehen. Doch folgende Richtlinien helfen bei einem guten Index-Aufbau:

  1. Für eine Query, die über 3 Attribute joint, legt man für diese 3 Attribute den Index an
  2. Die Attribute, die im Join mit „=“ verglichen werden (EquiJoin), werden an den Anfang des Index gestellt
  3. Das Attribut, nach dem sortiert wird oder Bereichs-Abfragen stattfinden, kommt hinten hin
  4. Hat man einen Index über die Spalten (a,b,c) und einen Index über die Spalten (a,b), kann der (a,b)-Index entfallen, da der (a,b,c)-Index diese Anfragen auch durchführen kann.
  5. Die Spalten, die in Queries mit „=“ verglichen werden, sind im Index vertauschbar. Das kann man nutzen, um 4. optimal auszunutzen.

Zurück zum Beispiel

Um die Query im oberen Beispiel also effizient abarbeiten zu können, ist folgender Index empfehlenswert:
Index(ShopID, SubID, Timestamp)

Die beiden Equi-Joins ShopID und SubID sind normale O(log(n))-Lookups auf dem Index. Hat man diese Range eingeschränkt, besteht die Range nur noch aus einer nach Timestamp sortierten Liste des über ShopID und SubID festgelegten Items. Aufgrund der ORDER-BY-DESC-Klausel weiß der Index nun, dass er aus der sortierten Liste das letzte Item zuerst auslesen muss. Die LIMIT-1-Klausel bricht beim Auslesen des ersten Items ab. Effektiv wurde also O(log(n)) Zeit in der inneren Schleife verbraucht.

Fazit

Zu jeder noch so komplizierten Query lässt sich ein Multi-Index finden, der die Joins optimiert. Software von Launix wird also auch bei großen Datenmengen effizient laufen.

Mit SQL Statistiken errechnen

In 99% der Fälle wird SQL zum Ablegen und Auslesen von Daten aus einer Datenbank benutzt. Doch die wenigsten wissen, dass man mit SQL auch komplizierte statistische Berechnungen durchführen kann.

Geschichte

1970 wurden Relationale Datenbanken erstmals erwähnt. Ihre Entwicklung weg von der Schritt-für-Schritt-Programmierung hin zu deklarativer, der Mathematik ähnlicher, Ausdrucksweise bei der Berechnung mit Daten, führte zu einer rasanten Entwicklung in der Datenverarbeitung. Man trennte auf einmal die Verwendung der Daten von der Speicherung. Während sich die Anwendung darum kümmert, was mit den Daten geschieht und was sie bedeuten, organisiert sich das Datenbanksystem selbstständig, indem es Speicherstrukturen optimiert, Indizes anlegt und Anfragepläne umschreibt und optimiert. Auf diese Weise entwickelt man einmalig beispielsweise statistische Formeln und anschließend kann jedes SQL-fähige Datenbanksystem diese ausrechnen. Werden beispielsweise die Datenbestände größer, kann man über ein kommerzielles DBMS nachdenken.

Der Group-Operator

Mit der GROUP BY-Klausel von SQL sortiert man die einzelnen Datensätze in Kategorien ein. Der Group-Operator ist die Grundlage für alle Statistiken, denn er fässt Datensätze zusammen. Mit dem Gruppierungsausdruck gibt man an, nach welchem Merkmal Datensätze zusammengefasst werden. Die Wahrscheinlichkeit P(A | B) berechnet man mit beispielsweise mit SELECT .... GROUP BY B. Der Gruppierungsausdruck kann sowohl Spalten enthalten (beispielsweise gruppiere Umsätze nach Kategorie), aber auch Berechnungen (gruppiere nach Tageszeit des Bestelldatums, gruppiere nach Wochentag, gruppiere nach unter- und über 1.000€ Umsatz).

Der SUM- und COUNT-Operator

Summen eignen sich, um Größenvergleiche numerischer Werte zu ermöglichen. Beispielsweise lässt sich der Umsatz einer Sparte aufsummieren. Beim Zählen ist es genau so, nur dass jeweils eine 1 aufsummiert wird.

Der Heilige Gral: AVG

Mit der AVG-Funktion berechnet man normalerweise Durchschnitte, beispielsweise das durchschnittliche Gehalt einer Abteilung. Wir Statistiker können aber wesentlich mehr damit anstellen. Misst man beispielsweise den Durchschnitt eines boolschen Ausdrucks, lässt sich eine Prozentzahl berechnen. Beispiel: SELECT AVG(Alter < 18) FROM Besucher errechnet, welcher Anteil der Besucher unter 18 Jahren sind.

Insbesondere in der Wahrscheinlichkeitsrechnung ist der AVG-Operator essenziell, denn man kann den Satz von Bayes prima in SQL ausdrücken, indem man einfach den Durchschnitt aller Wahrscheinlichkeiten gruppiert nach der Bedingung errechnet. Was man damit anstellen kann, können Sie im Beitrag über Wahrscheinlichkeiten nachlesen.

Access Datenbank programmieren – Umstieg auf SQL

Sie haben einige Daten in Ihren bereits vorhandenen Access-Datenbanken und benötigen jetzt eine Anpassung oder planen einen Aus- bzw. Umstieg? Dann lesen Sie diesen Artikel!

Umstieg auf SQL-basierte Datenbank

Wie bereits im vorangegangenen Artikel beschrieben, bieten Access-Datenbanken Bequemlichkeit, allerdings auch Gefahren und Probleme bei der täglichen Handhabung. Auf der anderen Seite zieht jeder Einsatz einer SQL-basierten Datenbank eine Software-Entwicklung mit sich. Dieses Thema möchte ich in diesem Artikel genauer beleuchten, um Sie aufzuklären, was Sie erwartet:

Schritt 1: Tabellen-Entwurf

Tabellen in SQL funktionieren wie in Access. Allerdings ist man bei Access dazu geneigt, weniger Tabellen anzulegen und Fremdschlüsselbeziehungen direkt in die Tabellen aufzunehmen. Wie bereits im vorangegangenen Artikel beschrieben, verstößt das gegen die erstrebenswerte Datenbank-Normalform. Hinzukommen zu den Tabellen werden wahrscheinlich noch eine Nutzer-Liste, um Netzwerk- und Internetzugriffe auf Ihre Software mit Nutzername und Passwort gegen Fremdeingriffe abzuschirmen.

Schritt 2: Entwicklung der Geschäftslogik

Die Geschäftslogik beschreibt die Aktionen, die Anwender in der Software tun können, bzw. dürfen. Eine Aktion wäre beispielsweise das Hinzufügen eines Kundendatensatzes, eine andere das Entfernen desselben. Ebenfalls zur Geschäftslogik gehören Abfragen, wie beispielsweise die Auflistung aller Kundendatensätze, der Abruf eines einzelnen Kundendatensatzes, sowie seiner Adressen oder auch das Abrufen von statistischen Daten, die anschließend in einem Diagramm dargestellt werden sollen.

Schritt 3: Entwicklung der Oberfläche

Jede Aktion der Geschäftslogik muss in der grafischen Oberfläche irgendwo verankert werden. So wird die Aktion „Kundensatz hinzufügen“ beispielsweise durch ein Formular realisiert. Von grafischen Oberflächen kann es mehrere Varianten geben, solange alle auf dieselbe Geschäftslogik zugreifen. So kann beispielsweise eine Tablet-Version der Software angefertigt werden, die lediglich das Statistik-Diagramm anzeigt, sowie erlaubt, zum Kunden, zu dem man gerade fährt, Notizen anzulegen.

Schritt 4: Installation, Test, Nutzung und Service

Planen Sie auf alle Fälle zusätzlich zum Software-Erstellungs-Budget Rücklagen für eine Weiterentwicklung ein. Haben Sie erst einmal eine Software im Einsatz, fallen Ihnen noch viele Dinge ein, die man besser machen kann. Auch Gesetzesänderungen oder nichtkonformes Kundenverhalten können eine Weiterentwicklung erforderlich machen.

Fazit

Machen Sie sich klar, was eine Softwareentwicklung bedeutet. Lassen Sie sich nicht von den hohen Anfangskosten abschrecken. Haben Sie erst einmal eine programmierte Software im Einsatz, kommen Sie damit besser.

Unterschiede Access vs SQL-basierte Datenbanken

Es gibt viele Datenbank-Systeme. In diesem Artikel möchte ich die grafische Datenbank-Oberfläche MS Access mit den eher technischen SQL-Datenbanken vergleichen.

Vorteil von Access: Einfacher Zugang

Der entscheidenste Vorteil von Access ist, dass Sie sofort loslegen können: Tabellen anlegen, Formulare kreieren oder generieren lassen, Abfragen und Berichte zusammenklicken. SQL ist da wesentlich technischer. Sie legen die Tabellen entweder über die SQL-Schnittstelle, also mit rohem SQL, an oder bedienen sich eines grafischen Tools. Bei Formularen, Abfragen und Berichten spätestens benötigen Sie Programmierkenntnisse oder einen Programmierer. Denn SQL-Datenbanken sind vorrangig als Datenanbindung für individuell programmierte Software geeignet. SQL-Datenbanken trennen die Darstellung und Editierung der Daten klar von der Verarbeitung und Speicherung.

Vorteil von SQL: Große Datenbestände und Netzwerke

SQL-Datenbanken sind prinzipiell über ein Netzwerk mit dem Anwender bzw. der Anwendung, die die Datenbank nutzt, verbunden. Dadurch erwächst der Vorteil, dass mehrere Nutzer auf die Datenbank zugreifen können. Das ist bei MS Access zwar auch möglich über eine Windows-Ordnerfreigabe, hat sich aber bei vielen Zugriffen als problematisch herausgestellt.

Sobald größere Datenmengen ins Spiel kommen, ist SQL klar im Vorteil. SQL-Datenbanken verwenden ausgefeilte Techniken wie z.B. Indizes, Caches, materialisierte Views und vieles mehr. Moderne SQL-Datenbanken arbeiten mit Terabyte-weise Daten, die über mehrere Rechner verteilt werden können und Millionen von Anfragen pro Sekunde gleichzeitig bearbeiten können. MS Access hat hingegen schon bei mehreren tausend Einträgen Probleme mit der Performance.

Unschönes Datenbank-Design ins Access

Die direkte Anzeige von Tabellen in Access führt zu einem fatalen Anwenderverhalten: Denormalisierten Tabellen. Was sind denormalisierte Tabellen? Das Thema hier auszuführen, macht keinen Sinn. Sehen Sie sich aber den Wikipedia-Artikel zu Normalisierung an, kann man erahnen, dass normalisierte Tabellen die optimale Speicherform sind, allerdings in Access schwer zu realisieren. Da sich normalisierte Tabellen in Access schwerer ansehen lassen (man müsste alles über Formulare und zwischengeschaltete Views erledigen), tendieren viele Access-Nutzer dazu, denormalisierte Tabellen zu erstellen. Das verbraucht unnötig Speicher und nachfolgende Analysen der Daten werden erschwert.

Plattformunabhängigkeit

Auch hier hat SQL die Nase vorn: Während MS Access nur auf einigen Windows-Versionen läuft, gibt es SQL-basierte Datenbanken auf jedem Blackberry, Android-Handy und -Tablet, Apple-Produkten, PCs, Servern und sogar eingebetteten Systemen wie Heizungsreglern. Gerade wenn Sie viel mobil unterwegs sind, kann ein Zugriff auf Ihre Unternehmensdaten übers Mobilfunknetz einen klaren Vorteil für Sie bedeuten.

Aufwendigere Anwendungsentwicklung bei SQL

Eine SQL-Datenbank kann nie allein dastehen. Für jede Datenbank muss immer eine dazugehörige Software programmiert werden, die die Formulare, Tabellen-Ansichten und Diagramme bereitstellt. Sie erkaufen sich quasi Flexibilität, Plattformunabhängigkeit und Performance mit höheren Einstiegskosten.

Fazit

Der Marktanteil von Access wird weiter schrumpfen. Doch die umständlichere Entwicklung mit SQL-Datenbanken wird viele, vor allem kleinere Firmen, noch davon abhalten. Für diese Anwender wird wohl eine Standardsoftware herhalten müssen, es sei denn, der Launix Data Organizer kommt vorher auf den Markt.