hoch

Datenbank-Optimierung - mein Highlight der Woche

Bei meiner Arbeit an der Uni Bern war ein Grossteil der Zeit in die Optimierung von Datenbank-Zugriffen geflossen. Das betraf hauptsächlich ein System für ein Portal für Dozierende und Studierende mit Stundenplänen, Kurseinschreibungen, Feeds zu etlichen Themen und nach Studienjahr getrennt, Kalendersynchronisation von personalisierten Kalendern uvm. Jenes Portal ist uralt und wurde einmal mit PHP4 entwickelt und sollte abgelöst werden. Wurde es aber nicht, sondern es wurde vor vielen Jahren mühsam unter PHP5 lauffähig gemacht, aber der Code blieb noch immer zumeist prozedural, mit vielen Includes und gespickt mit allen erdenklichen Highlights an Programmiersünden, sei es Wartbarkeit, Caching/ Performance, SQL-Injection oder Verständnis von Algorithmen und Gestaltung von Datenbankabfragen. Seit dem ersten Ablösetermin sind nun 8..9 Jahre vergangen … aber Herbst 2019 wird es endlich(!!) abgelöst. Heisst aber: bis dahin muss es weiter am Leben erhalten werden.

Es wurden 5 Applikationsteile, die “am meisten weh tun” ausgemacht und jene optimiert. Letzten Dienstag wurde es eingespielt. Doch, es hat sich gelohnt - da ist so ein markanter Abfall:

2018-02-18-dbperformance-queries-by-week.png

Man könnte meinen: da ist was kaputt. Aber nein: es funktioniert genau gleich!!
Ich hoffe, ich kann euch mit diesem Praxis-Beispiel motivieren: macht einmal eine Performance-Analyse und schaut genauer auf die Top 3!

[Read More…]

Artikel weiterempfehlen: Google + Facebook

Mysql-connect sehr langsam?

Für Windows gibt es fixfertige Pakete für die Kombination Apache + Php + Mysql + X, wie z.B. XAMPP oder Wamp.

Für ein kleines Projekt habe ich auf eine solche zurückgegriffen und irgendwie war es langsam. Was genau langsam war, war nach einigem Debugging lokalisiert:

(...)
$iStart=microtime(true);
mysql_connect($hostname . ":" . $hostport, $username, $password);
echo microtime(true) - $iStart."s to open DB $database<br>";
(...)

Das mysql_connect() brauchte regelmässig 1 Sekunde - die anschliessenden Queries 0.00x Sekunden.

Ursache ist der Zugriff mit dem Hostnamen “localhost” auf die Loopback-Adresse. Wenn man den Mysql-Service auf eine IP-Adresse bindet, geht es massiv schneller. Konfiguriert wird dies in der my.ini im Installationsverzeichnis von Mysql. Oder man verbindet sich auf die IP-Adresse 127.0.0.1.
Ach, und unter Windows den Eintrag lower_case_table_names=2 nicht vergessen - daher schiebe ich es mal hinterher:

(...)
bind-address="127.0.0.1"
bind-address = ::1          # fuer ipv6
lower_case_table_names=2 
(...)

Nach Änderung der Konfiguration muss man den Mysql-Dienst neu starten, damit es wirksam wird.

Weiterführende Links:

Artikel weiterempfehlen: Google + Facebook

PHP mit Sqlite - mein erster Gehversuch

Ich habe mal einen Download-Zähler gebaut: mittels .htaccess werden alle Dateizugriffe auf ein PHP-Skript umgebogen, welches einmal die angeforderte Datei ausliefert und den Zugriff protokolliert.

In PHP5 ist Sqlite direkt mitgeliefert. Die Sqlite Datenbank ist eine Textdatei, auf die ohne einen laufenden Server zugegriffen wird. Für kleine Webauftritte, wo das Webroot nicht auf einem NFS- oder SMB-Share liegt, ist dies problemlos.

Der wesentliche Vorteil einer SQl-Datenbank zu einer (CSV-) Textdatei ist die Auswertung der Daten: mit SQL Queries kommt man schnell zu den gewünschten Informationen.

Ich definiere mal in PHP eine Variable mit dem Dateinamen zur Datenbank:

$sqliteDB = $_SERVER['DOCUMENT_ROOT']."/sqlite/downloads.sqlite";

In dieser Datenbank ist - weil es zum Einstieg einfacher ist: mit einem grafischen Tool - eine Tabelle angelegt worden:

CREATE TABLE "downloadcount" (
   "id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE ,
  "time" DATETIME,
  "file" TEXT,
  "ext" TEXT,
  "ip" TEXT,
  "referrer" TEXT,
  "usaeragent" TEXT
)

Dann muss man nur noch wissen, welcher Sqlite Treiber beim Provider vorhanden ist. Das kann wahlweise Sqlite2, Sqlite3 oder PDO Sqlite sein. Die Versionen unterscheiden sich bei den Kommandos zum Öffnen der Datenbank oder beim Aufruf zum Ausführen eines Queries.

Bei Sqlite 3

$db = new SQLite3($sqliteDB);

Bei PDO Sqlite 3:

$db = new PDO("sqlite:".$sqliteDB);

Ich beziehe mich mal auf die PDO Variante…
So öffnet man eine DB und fügt mit Ausführung eines SQL Statements einen Eintrag hinzu. Eingefügt werden hier die aktuelle Uhrzeit (des Requests), Dateiname und dessen Erweiterung, IP-Adresse des Aufrufers, Referrer und User-Agent.

// $filename enthält den Dateinamen der heruntergeladenen Datei
$db = new PDO("sqlite:".$sqliteDB);
if ($db) {
  $path_info = pathinfo($filename);
  $ext=$path_info['extension'];

  $sql="INSERT INTO `downloadcount`
    (`time`, `file`, `ext`, `ip`, `referrer`, `useragent`)
    VALUES ('".date("Y-m-d H:i:s")."', '" . $filename . "', '".$ext."', '" . getenv("REMOTE_ADDR") . "',  '" . getenv('HTTP_REFERER') ."','".getenv('HTTP_USER_AGENT')."');
  ";

  // echo "SQL:<br>$sql<br>";
  $db->exec($sql);
}

Weiterführende Links:

Artikel weiterempfehlen: Google + Facebook

HeidiSQL 5 - Mysql-GUI für Windows

HeidiSQL 5 ist eine kostenlose grafische Oberfläche für Mysql-Server. Es ist ein reiner Windows-Client.

Die neue Version 5 von HeidiSQL habe ich mir heute heruntergeladen und habe es als portable Version am Laufen.
Version 4 wollte unter Windows 7 immer das Admin-Passwort haben, warum auch immer (vielleicht hab auch ich das verbockt)…

2010-04-11-heidisql.jpg
[Read More…]

Artikel weiterempfehlen: Google + Facebook