Das Putzlowitsch Test- und SEO-Blog

Alte PHP-Version 5.6 bei Strato jetzt auf PHP 7.2 umstellen

Freundliche Nachricht von Strato

Gestern erreichte mich eine E-Mail von meinem Webhoster Strato:

„Wichtig: Ihre PHP-Version ist veraltet
Seit Januar 2019 ist Ihre PHP-Version 5.6 veraltet und es stehen keine Sicherheitsupdates mehr zur Verfügung.
Wir lassen Sie nicht im Regen stehen! Bis zum 15.07.2019 führen unsere Entwickler kostenlos die Sicherheitsupdates für Ihre Websites fort.

Sie möchten weiterhin Ihre alte PHP-Version behalten?
Dann übernehmen wir die Aufgabe der PHP Community und führen weiterhin selbst die Sicherheitsupdates für PHP 5.6 durch. Bitte haben Sie Verständnis, dass hierdurch Wartungsaufwand entsteht, den wir ab dem 16.07.2019 mit 5,33 Euro pro Auftrag pro Monat in Rechnung stellen. Dies nennt sich PHP Extended Support. …“

Eigentlich hatte ich mein Webhostingpaket bei der STRATO AG schon auf PHP 7.2 umgestellt, dachte ich.

Alles eine Einstellungssache

Also habe ich mich schnell im Strato-Kundenmenü angemeldet und wurde gleich mit einem Popup-Fenster begrüßt.

Strato-Webhosting: Veraltete PHP-Version-Hinweis

Ja aber ich habe doch schon vor Wochen auf PHP 7.2 umgestellt. Also fix mal auf den Button [PHP-Versio ändern] geklickt und siehe da:

Strato-Webhosting: PHP-Version einstellen

Hab ich es doch gewußt:
„Sie verwenden zur Zeit folgende PHP-Version: PHP 7.2

Stimmt im Prinzip auch, nur weiter unten steht dann der entscheidende Hinweis:
„Achtung: Sie nutzen in mindestens einer .htaccess Datei auf Ihrem Webspace PHP 5.6/7.0.“

Also gammelt da in einem nicht mehr aktiven Projekt irgendwo noch eine .htaccess-Datei herum, in der ich eine PHP 5er Version aktiviert hatte. Nur welche das ist, sagt mir die freundliche Strato-Meldung nicht.

Suchen und Finden

Mit meinem Basiswissen Unix/Linux sollte das aber kein Problem sein, zumal es bei meinem Paket auch ein SSH-Login gibt.
Also einfach per SSH im Paket anmelden und mit „grep -r …“ den Übeltäter aufspüren. Denkste. Bei SunOS/Solaris, das auf den Webservern bei Strato läuft, gibt es kein rekursives grep.

Aber es gibt ja das Internet und so habe ich schnell die passende Kombination aus find und grep gefunden:

find . -type f -name ".htaccess" -exec grep -l "application/x-httpd-php5" {} +

Und tatsächlich habe ich drei .htaccess-Dateien mit einer alten PHP5-Konfiguration gefunden.

Strato-Webhosting: ssh

In zwei Fällen war die Zeile

# AddType application/x-httpd-php5 .php

auskommentiert, also nicht mehr aktiv. Nur beim Test-Projekt /neueseite/test/ war der Eintrag „aktiv“, allerdings war die Installation nicht mehr mit einer Domain/Subdomain verknüpft und somit nicht aufrufbar.

Die beiden Ordner /schnurpsel_29/ und /neueseite/test/ habe ich einfach komplett entsorgt und bei der Gelegenheit auch sonst noch ein wenig im Webspace aufgeräumt.

Das ist mit „rm -r …“ in NullKommaNix erledigt, viel schneller als beim rekursiven Löschen per FTP.
Allerdings sollt man sich sicher sein, was man tut, denn „rm -r“ haut ohne Nachfrage alles weg. Und weg ist weg. :-)

Ein Kommentar »

Direkte Bild-Aufrufe auf Seite weiterleiten – so gehts

Das Problem

In den letzten Tagen ist die Aufregung ob der neuen Google-Bildersuche recht groß und viele versuchen, einen Ausweg aus den sinkenden Besucherzahlen zu finden.

In der neuen Bildersuche werden die Bilder direkt in Original-Auflösung auf der Ergebnisseite geladen. Der Nutzer hat also wenig Anlaß, die Ursprungsseite zu besuchen.

Google-Bildersuche: Links zu Seite/Bilder

Immerhin gibt es vier Links (grün), die den Benutzer auf die Ursprungsseite mit dem Bild führen. Dazu kommt ein Link direkt zum Bild [Bild ansehen] und indirekt die Möglichkeit, per Rechtsklick und „Grafik anzeigen“ nur das Bild aufzurufen.

Der direkte Link zum Bild bringt allerdings keine Besucher auf die Seite. Daher gibt es die Idee, den direkten Aufruf eines Bildes aus der Bildersuche auf eine Seite mit dem Bild umzuleiten.

Achtung!
Lest bitte vorher die Hinweise von Google zu „Bilder-Cloaking“ und überlegt Euch, ob Ihr das Riskio eingehen wollt.

So gehts

Um zu erkennen, ob jemand von der Bildersuche kommt, kann man den Referrer auswerten. Vereinfacht gesagt, könnte man folgende Regel formulieren:

„Ist die Referrer-Domain google.* und die angeforderte Datei ein Bild (jpeg,png,…), dann leite den Nutzer auf eine Seite mit dem Bild um.“

In der .htaccess könnte das so aussehen:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

RewriteCond	%{REQUEST_FILENAME} -f
RewriteCond	%{HTTP_REFERER}	^http(s)?://(www\.)?google [NC]
RewriteRule	\.(jpg|png|gif)$	/redirect.php	[L]
</IfModule>

Zunächst wird Rewrite eingeschaltet und die Basis festgelgt.
Dann wird geprüft, ob es die angeforderte Datei überhaupt gibt und ob der Referrer Google ist. Falls ja und die Datei ein Bild ist, wird das PHP-Skript zur Weiterleitung aufgerufen.

So weit, so gut, nur gibt es noch einige Probleme zu lösen.

Leider wird der Referrer auch gesendet, wenn das Bild als Bild auf der Google-Seite geladen wird. Da soll natürlich keine Weiterleitung erfolgen, weil das im Kontext eines Bilder zu einem Fehler führt. Kann man also unterscheiden, ob das Bild geladen wird oder ein Link auf das Bild aufgerufen wird? Ja, mann kann. Zumindest meistens.

Außerdem wird ein bereits geladenes Bild vom Browser im Cache vorgehalten, was zu unvorhergesehenen Ergebnissen bei der Weiterleitung führen kann. Kann man das verhindern? Ja, man kann.

Meine Problemlösungen

Als technische Basis setze ich einen Apache-Server mit den aktiven Modulen mod_rewrite, mod_headers und mod_setenvif voraus. Wobei das Modul mod_setenvif nicht zwingend erforderlich ist, es macht die Sache aber übersichtlicher:

<IFModule mod_headers.c>
Header	set	 Cache-Control "no-cache, no-store, must-revalidate"	env=NO_CACHE
Header	unset	 Expires	env=NO_CACHE
Header	unset	 Last-Modified	env=NO_CACHE
Header	unset	 ETag	env=NO_CACHE
</IfModule>

<IfModule mod_setenvif.c>
SetEnvIf Accept "text/html"	REQ_HTML=1
SetEnvIf Referer "^https?://(([^\.]+?\.)?([^\.]+?\.)?[^\.]+?)/"	DOM_REFERER=$1
</IfModule>

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /bilder

RewriteCond	%{REQUEST_FILENAME} -f
RewriteRule	\.(jpg|gif|png)$	-	[NC,C]

RewriteCond	%{ENV:DOM_REFERER}	google\.de$ [NC,OR]
RewriteCond	%{ENV:DOM_REFERER}	google\.at$ [NC,OR]
RewriteCond	%{ENV:DOM_REFERER}	google\.ch$ [NC,OR]
RewriteCond	%{ENV:DOM_REFERER}	example\.com
RewriteRule	.*	-	[E=DO_RDR:1,E=NO_CACHE:1]

RewriteCond	%{ENV:REQ_HTML} 1
RewriteCond	%{ENV:DO_RDR} 1
RewriteRule	([^-]+)-([0-9]+)\.(jpg|gif|png)$	/bild-$1-$2.html	[R=302,L]
</IfModule>

Zur Unterscheidung von Bildaufruf (img src=…) und Link verwende ich den Wert von „Accept“ im HTTP-Request-Header. Nach meiner Beobachtung enthält dieses Header-Feld bei Bild-Aufrufen nicht den Typ „text/html“, beim Aufruf von Links, auch zu Bildern, aber schon. Wenn also „text/html“ im Accept-Header zu finden ist, dürfte es sich um den Link zum Bild und nicht um das Laden des Bildes in der Google-Ansicht handeln.

<IfModule mod_setenvif.c>
SetEnvIf Accept "text/html"	REQ_HTML=1
SetEnvIf Referer "^https?://(([^\.]+?\.)?([^\.]+?\.)?[^\.]+?)/"	DOM_REFERER=$1
</IfModule>

Den Accept-Header werte ich in einer SetEnvIf Anweisung aus und setze eine entsprechende Variable, die ich später in den Rewrite-Regeln auswerten kann. Zudem extrahiere ich in dem Block den Domain-Namen aus dem Referer, da ich diesen auch in anderen Rewrite-Regeln benötige.

RewriteCond	%{REQUEST_FILENAME} -f
RewriteRule	\.(jpg|gif|png)$	-	[NC,C]

Mit den Rewrite-Regeln prüfe ich zunächst die Existenz der Datei und über die Datei-Erweiterung, ob ein Bild aufgerufen wird. Falls nicht, wir der zweite Block der Rewrite-Regeln gar nicht erst ausgeführt.

RewriteCond	%{ENV:DOM_REFERER}	google\.de$ [NC,OR]
RewriteCond	%{ENV:DOM_REFERER}	google\.at$ [NC,OR]
RewriteCond	%{ENV:DOM_REFERER}	google\.ch$ [NC,OR]
RewriteCond	%{ENV:DOM_REFERER}	example\.com
RewriteRule	.*	-	[E=DO_RDR:1,E=NO_CACHE:1]

Im zweiten Block wird eine Liste von Referrer-Domains abgearbeitet, für die die Weiterleitung erfolgen soll. In dem Fall sind es die drei Google-Domains, von denen die meisten meiner Besucher kommen (exemple.com ist nur ein Platzhalter). Die Abfrage nach dem Referer kann man natürlich auch anders gestalten. Das hängt halt davon ab, was man damit erreichen will. Hier setze ich mir wieder ein Flag (DO_RDR), das ich später für die Weiterleitung auswerte.

<IFModule mod_headers.c>
Header	set	 Cache-Control "no-cache, no-store, must-revalidate"	env=NO_CACHE
Header	unset	 Expires	env=NO_CACHE
Header	unset	 Last-Modified	env=NO_CACHE
Header	unset	 ETag	env=NO_CACHE
</IfModule>

Außerdem setze ich einen Wert (NO_CACHE), mit dem am Ende geprüft wird, ob das Caching deaktiviert werden soll. Der Block mod_headers steht zwar am Anfang, der Webserver führt diese Anweisungen aber erst ganz zum Schluß aus, kurz bevor die Antwort an den Client gesendet wir. Damit wird das Caching des von Google direkt geladenen Bildes verhinert.

RewriteCond	%{ENV:REQ_HTML} 1
RewriteCond	%{ENV:DO_RDR} 1
RewriteRule	([^-]+)-([0-9]+)\.(jpg|gif|png)$	/bild-$1-$2.html	[R=302,L]

Im dritten Rewrite-Block erfolgt dann die Weiterleitung, falls es sich um einen Link-Request (REQ_HTML) handelt und eine Weiterleitung überhaupt ausgeführt werden soll (DO_RDR).

Wohin weiterleiten?

Ein weiteres Problem kann die eigentliche Weiterleitung sein. Wohin soll die Reise gehen?

Im Beispiel ist das relativ einfach. Die Bilder liegen in einem Unterverzeichnis /bilder/ und der Dateinamen besteht aus Bezeichnung und laufender Nummer. Die Zielseiten mit den Bildern bestehen auch aus Bezeichnung und laufender Nummer. Damit läßt sich schon in der .htaccess Datei die Weiterleitungsregel unmittelbar formulieren.

/bilder/tomaten-7.jpg -> /bild-tomaten-7.html
/bilder/banane-23.jpg -> /bild-banane-23.html
...

Schön, wenn man so eine klare Struktur für seine Bilder hat. Ich habe die leider nicht. :-)

RewriteCond	%{ENV:REQ_HTML} 1
RewriteCond	%{ENV:DO_RDR} 1
RewriteRule	.*	/rdr.php	[L]

Also muß die Weiterleitung z.B. von einem PHP-Skript erledigt werden, in dem man dann praktisch beliebige Weiterleitunsziele adressieren kann.

In WordPress gibt es für die über die Mediathek hochgeladenen Bilder jeweils eine Attachment-Seite. Nun könnte man sich die Informationen zum Weiterleitungsziel aus der WP-Datenbank holen. Aus Performance-Gründen habe ich da einen etwas anderen Weg gewählt.

Für WordPress, wie z.B. hier bei schnurpsel.de, sieht das rdr.php-Skript so aus:

<?php
define( 'THISPATH', dirname(__FILE__) . '/' );
@include( THISPATH.'redir.php' );

function set_404() {
	header( "HTTP/1.0 404 Not Found", true, 404 );
	echo <<<EOT
<!DOCTYPE html>
<html>
<head><title>404 Not Found</title></head>
<body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>
EOT;
	exit;
}

function set_header( $ctype ) {
	@header( "Content-type: $ctype" );
	@header( 'Cache-Control: no-cache' );
	@header( 'Cache-Control: max-age=0', false ); 
	@header( 'Expires:'.gmdate('D, d M Y H:i:s', 0 ).' GMT' );
}

function redirect( $url, $status = 302 ) {
	@header( 'Cache-Control: no-cache, no-store, must-revalidate' );
	@header( "Location: $url", true, $status );
	exit();
}

$img_uri = urldecode( $_SERVER['REQUEST_URI'] );
$redir_url = $redir_b[$img_uri];

if( !$redir_url && @preg_match( '~(.+?)-(1600|1200)\.(jpg|png|gif)$~', $img_uri, $treffer ) ) {
	$redir_url = $redir_b[$treffer[1].'.'.$treffer[3]];
}

if( $redir_url )
	redirect( $redir_url );
else {
	$img_file = THISPATH.$img_uri;
	$img_size = @getimagesize( $img_file );
	if( $img_size ) {
		set_header( $img_size['mime'] );
		@readfile( $img_file );
		exit;
	}
}
set_404();
?>

Download: rdr.zip

In meinem rdr-Skript includiere ich eine weitere PHP-Datei (redir.php), die nur ein Array mit den Weiterleitungszielen für die Bilder enthält. Falls kein Weiterleitungsziel gefunden wird, gebe ich einfach das Bild selbst aus.

Die redir.php PHP-Datei lasse ich mir von einem Skript durch WordPress erstellen:

<?php
define( 'THISPATH', dirname(__FILE__) . '/' );
define( 'WP_USE_THEMES', false );
define( 'USE_ATTACHMENT_URL', true );

@include( THISPATH.'redir.php' );

require('./wp-blog-header.php');

echo '<pre>';

$args = array( 'post_type' => 'attachment', 'posts_per_page' => -1, 'post_mime_type' => 'image', 'post_parent' => null ); 
$attachments = get_posts( $args );
if ( $attachments ) {
	foreach ( $attachments as $post ) {
		$attachment_url = wp_get_attachment_url( $post->ID );
		$attachment_uri = @parse_url( $attachment_url, PHP_URL_PATH );
		if( USE_ATTACHMENT_URL )
			$page = get_attachment_link( $post->ID );
		else
			$page = get_permalink( $post->post_parent );
		if( $page && $attachment_uri && !$redir_b[$attachment_uri] ) {
			if( strpos( $page, 'attachment_id' ) === false ) {
				$redir_b[$attachment_uri] = $page;
				echo "+ $attachment_uri -> $page\r\n";
			}
			else
				echo "- $attachment_uri -> $page\r\n";
		}
		else
			echo "* $attachment_uri -> $page\r\n";
	}
}

$export_data = "<?php\r\n\$redir_b = ";
$export_data .= var_export( $redir_b, true );
$export_data .= ";\r\n\r\n?>";
file_put_contents( THISPATH.'new_redir.php', $export_data );
echo '</pre>';
?>

Download: get-redir.zip

Mit der Konstante ‚USE_ATTACHMENT_URL‘ wird festgelegt, ob die Weiterleitung auf die Attachment-Seite (true) oder zur Artikel-Seite mit dem Bild (false) erfolgen soll.

Zum Anfang wird die bestehende ‚redir.php‘ geladen. Es werden dann nur Einträge hinzugefügt, die es noch nicht gibt.

Außerdem prüfe ich, ob es die Attachment-Seite wirklich gibt, denn für Bilder ohne Eltern-Seite bzw. Bilder in nicht veröffentlichten Artikeln wird kein Permalink zurückgeliefert, sonder nur die URL mit dem ‚attachment_id‘-Parameter.

Am Ende wird eine neue Datei ’new_redir.php‘ geschrieben, mit der man dann die alte ‚redir.php‘ ersetzen kann.

Folgende Dateien sind an der Methode beteiligt:
/rdr.php
/redir.php
/wp-content/uploads/.htaccess

In der .htaccess-Datei muß die RewriteBase entsprechend angepaßt werden:

RewriteBase /wp-content/upload

Für meine Putzlowitscher Zeitung enthält das Array etwas mehr als 2000 Einträge. Das ergibt eine Dateigröße von ca. 350k. Wer deutlich mehr Bilder in WP verwaltet, muß sich ggf. etwas anderes einfallen lasse.

So ein Array hat aber den Vorteil, daß ich darin auch beliebige, andere Weiterleitungsziele definieren kann.

Noch ein paar Tips und Hinweise

Falls sich alle Eure Bilder in einem Unterverzechnis befinden, bei WordPress z.B. /wp-content/uploads/, dann packt die .htaccess-Datei genau dort rein. Für alle anderen, normalen Seitenaufrufe wird sie dann gar nicht erst abgearbeitet.

Was irgendwie möglich ist, sollte schon in der .htaccess-Datei erledigt werden. Der Aufruf eines Skriptes, eventuell sogar mit Datenbankabfragen, kostet mehr Server-Leistung und verschlechtert die Performance.

Ihr könnt sogar unterscheiden, ob jemand den Button [Bild ansehen] angeklickt oder per Rechtsklick das Bild aufgerufen hat. Beim Rechtsklick wird ggf. vom Browser als Referer die komplette Google-Such-URL übermittelt. Das kann man zur Unterscheidung auswerten, z.B. ob der Parameter tbm=isch im Referer enthalten ist.

Das Speichern mit Rechtsklick auf das Original-Bild in der Bildersuche funktioniert nicht. Es wird die HTML-Seite des Weiterleitungs-Ziels gespeichert. :-)

Ich habe bisher nur mit wenigen Browsern getestet. Bei denen hat es aber funktionert, wie es soll.

Ich übernehme keine Haftung für Schäden, die möglicherweise durch die Umsetzung der hier vorgestellten Methoden entstehen.

14 Kommentare »

Strato aktualisiert endlich den WebDatabaseManager

Vor etwa 4½ Jahren hatte ich mal ein größeres Problem mit einer Datenbank bei Strato. Die technische Ursache war eine damals schon drei Jahre alte Version (2.6.4-pl3) der MySQL-Verwaltungssoftware phpMyAdmin.

Als ich nun heute mal wieder den WebDatabaseManager, der übrigens auch unter „Profi-Features“ in der Beschreibung der Webhostingpakete aufgeführt ist, für eine meiner Datenbanken startete, war ich doch positiv überrascht.

Strato WebDatabaseManager (phpMyAdmin 3.5.3)

Strato hat es nach nunmehr fast 7 Jahren geschafft, den Hosting-Kunden eine halbwegs aktuelle Version (3.5.3 vom Oktober 2012) von phpMyAdmin als WebDatabaseManager bereitzustellen.

Nun hängt nur noch 1&1 hinterher, da läuft immer noch das uralte phpMyAdmin 2.6.4-pl3.

Keine Kommentare »

Geschwindigkeit ist keine Hexerei

Googlebot Ladezeit

Daß das Strato-Shared-Webhosting und WordPress derzeit nicht gut zusammenpassen und warum das so ist, hatte ich vor einiger Zeit geschrieben. Auf Grund der schlechten PHP-Performance dauert das Laden einer WordPress-Seite mindestens 3,5 bis 4 Sekunden, auch wenn keine umfangreichen Plugins oder fette Themes installiert sind.

In den Google-Webmastertools kann man sich die Ladezeiten in einem Diagramm für die letzten drei Monate ansehen. Die Grafik oben zeigt den Verlauf für meine Seite schnurpsel.de. Bis Mitte Juli hatte ich alles bei Strato in meinem Webhostingpaket liegen. Allerdings nutzte ich bereits zu dieser Zeit eine externe Datenbank (bei Host-Europe), da es zeitweise bei Strato auch erhebliche Probleme mit dem Datenbankserver gab.

Im Juli bin ich dann schließlich mit der WordPressinstalltion zu All-Inkl umgezogen, hatte aber weiterhin die externe Datenbank bei HE im Zugriff. Der Umzug verlief bis auf die 410-Gone-Panne auch ganz gut. Die Geschwindigkeit hatte sich schon deutlich verbessert. Einen kleinen Performance-Schub gab es dann nochmal Anfang/Mitte September, da hatte ich dann auch die Datenbank zum Webhoster mit der WordPressinstallation geholt.

Die Geschwindigkeit liegt nun bei 1 bis 1,5 Sekunden für den Seitenabruf. Das ist zwar kein Spitzenwert, aber durchaus akzeptabel. Gut, WordPress ist keine ganz kleine Webapplikation und erfordert schon einiges an Ressourcen vom Webserver, aber trotzdem ist es auch auf mittleren Shared-Webhostingpaketen vernünftig einsetzbar. Dazu muß allerdings der Webserver ordentlich konfiguriert sein. Ich weiß ehrlich gesagt nicht, was da bei Strato die PHP-Performance so ausbremst, normal ist das aber nicht. Selbst auf einem vergleichbaren 1&1-Paket ist WP schneller, und 1&1 gilt allgemein auch nicht grad als Gschwindigkeits-Überflieger.

Man kann nur hoffen, daß sich da bei Strato mal etwas tut, vielleicht ja unter der Regie eines möglichen, neuen Besitzers.

Keine Kommentare »

Warum WordPress bei Strato so langsam ist

Eigentlich müßte ich besser sagen, was ist kein Grund dafür, daß WordPress beim Strato-Shared-Webhosting so langsam ist. Denn an einer vermeintlich schlechten Datenbankanbindung bzw. Datenbankperformance, wie man es oft in Foren oder auf Blogs lesen kann, liegt es nicht.

Datenbankgeschwindigkeit, der Test

Bei WordPress kann man sich alle Datenbankabfragen als SQL-String mit Ausführungszeiten und Aufrufhierarchie in Datenbank-Objekt unter $wpdb->queries speichern lassen. Dazu muß man in der wp-config.php die Konstante ‚SAVEQUERIES‘ mit true definieren:

define( 'SAVEQUERIES', true );

Genau das habe ich für die Startseite von schnurpsel.de gemacht und mir die Daten als PHP-Array in eine Datei geschrieben:

global $wpdb;
ob_start();
var_export( $wpdb->queries );
$out1 = ob_get_contents();
ob_end_clean();
plw123_debugfile_write( $out1 );

Diese Liste mit 51 SQL-Abfragen habe ich in ein einfaches PHP-Skript eingebunden und arbeite die Abfragen hintereinander ab. Es wird zunächst ein Connect zur Datenbank ausgeführt und anschließend folgende Schleife durchlaufen:

foreach( $sql_queries as $query ) {
	$dbd = @mysql_query( $query[0], $dbh );

	while( $row = @mysql_fetch_object( $dbd ) ) {
		$last_result[$num_rows] = $row;
		$num_rows++;
	}
	@mysql_free_result( $dbd );
	$num_queries++;
}

Es werden natürlich nicht nur die SQL-Abfragen ausgeführt, sondern auch die Ergebnisdatensätze mit mysql_fetch_object abgeholt. Nur die Ausgabe der Daten spare ich mir, das hat dann aber sowieso nichts mehr mit der Datenbank zu tun.

Datenbankgeschwindigkeit, das Ergebnis

Mal von ein paar Lastspitzen abgesehen, werden die 51 Abfragen und 539 Ergebnisdatensätze vom Strato MySQL 5 Server in etwa 0,2 Sekunden abgearbeitet. Man kann das hier [test-db-mysql5] live testen.

Ich habe das auch mal mit MySQL 4 probiert, da sind die Werte sogar noch etwas besser und liegen meist bei 0,1 Sekunden oder darunter [test-db-mysql4].

Und als dritten Test habe ich eine externe Datenbank (bei Host-Europe) eingebunden [test-db-ext]. Die 0,5 bis 0,6 Sekunden sind gar nicht mal so schlecht wenn man bedenkt, daß alle Daten über das Internet von Strato (Karlsruhe/Berlin) zu Host-Europe (Köln) und wieder zurück befördert werden müssen.

Mein Fazit

Die schlechte Geschwindigkeit von WordPress (und anderen umfangreichen PHP-Applikationen wie z.B. Joomla) liegt ursächlich nicht an einer schlechten Datenbankperformance, sondern vielmehr an einem nicht besonders schnellen Webserver/PHP.

Was hier nun im einzelnen das Problem ist, kann ich nicht sagen. Ein Geschwindigkeits-Nachteil ist sicher die Tatsache, daß PHP bei Strato als CGI läuft. Das bedeutet, daß für jeden Seitenaufruf ein neuer PHP-Prozeß gestartet werden muß. Konfigurationen, bei denen PHP als Apache-Modul läuft, haben da natürlich einen Geschwindigkeitsvorteil.
Vielleicht muß ja auch jede PHP-Datei bei Strato erst einen Sicherheitcheck durchlaufen, bevor sie geladen wird oder was auch immer.

Ein weiterer Hinweis für die mäßige PHP/Webserver-Performance sind auch die nicht besseren Ladezeiten des Strato Weblog-Basic, denn da ist überhaupt kein MySQL-Datenbankserver im Spiel. Die Daten liegen auf dem Webspace des Users und werden per SQLite eingebunden.

Trotz eigentlich nicht schlechter MySQL Datenbankgeschwindigkeit wird meine Startseite hier nicht schneller als in etwa 3,5 Sekunden geladen, dabei verwende ich fast eine WP-Standardkonfiguration ohne umfangreichen Plugins.

Meine Ausführungen tragen zwar nicht zur Lösung des Geschwindigkeitsproblems bei, aber vielleicht zum Verständnis der Ursache und Problematik an sich.

58 Kommentare »