Es sind nur ein paar Handgriffe, die Welten bewegen. Ich hatte eine SQL Abfrage mit ein paar Joins, die bei steigender Anzahl von Datensätzen bis zu 5 Minuten dauerte. Das konnte so natürlich nicht weitergehen, also hab ich kurz eine Relation mittels Fremdschlüssel in der Datenbank-Struktur realisiert und die Abfrage dauerte von nun an 2 Sekunden – Wahnsinn! Das Problem mit der Geschwindigkeit hatte ich übrigens auch bei jedem XT Commerce Shop mit mehreren Hundert oder Tausend Artikeln, bei dem DirectUrl für suchmaschinenfreundliche URLs installiert ist. Das Problem ist, das DirectUrl die Tabelle mit den Alias-URLs bei jeder Änderung des Produktkatalogs, der Kategorien und der Content Seiten neu erstellt. In Bezug auf das Bearbeiten von Produkten und Kategorien können wir das Laden von 5 Minuten auf 2 Sekunden verringern. Die folgende MySQL Code zeigt die modifizierte Tabellenstruktur mit Indizes für die DirectUrl-Alias-Tabelle.
url_md5 varchar(32) NOT NULL,
url_text varchar(255) NOT NULL,
products_id int(11) DEFAULT NULL,
categories_id int(11) DEFAULT NULL,
content_group int(11) DEFAULT NULL,
language_id int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (url_md5),
KEY url_text (url_text,products_id),
INDEX fk_products_description (products_id ASC) ,
CONSTRAINT fk_products_description
FOREIGN KEY (products_id)
REFERENCES products_description (products_id) ,
INDEX fk_categories_description (categories_id ASC) ,
CONSTRAINT fk_categories_description
FOREIGN KEY (categories_id)
REFERENCES categories_description (categories_id) ,
INDEX fk_languages (language_id ASC) ,
CONSTRAINT fk_languages
FOREIGN KEY (language_id)
REFERENCES languages (languages_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Hier wurden lediglich 3 Fremdschlüssel ergänzt, weil die Joins der Abfrage über diese Fremdschlüssel verlaufen: fk_products_description, fk_categories_description und fk_languages.
Wichtig ist hierbei das Stichwort InnoDb. Das Verknüpfen der Tabellen mit Fremdschlüsseln funktioniert in MySQL nur mit der Storage-Engine InnoDb. Also müssen alle Tabellen, die verknüpft werden sollen vom Typ InnoDb sein. In phpMyAdmin kann man dies unter Operations ändern. Ansonsten einen ALTER TABLE Befehl auf die betreffenden Tabellen ausführe. Im Falle von der DirectUrl Optimierung wären das diese hier:
ALTER TABLE categories_description ENGINE=InnoDb;
ALTER TABLE languages ENGINE=InnoDb;
Am saubersten ist es jedoch, die Struktur mit InnoDb neu zu erstellen und nachträglich die Datensätze mittels INSERTs einfügen.
So dann gehen wir noch kurz auf einen Fremdschlüsseleintrag in der Tabellenstruktur ein, hier nochmals ein Auszug aus der Struktur oben:
CONSTRAINT fk_categories_description
FOREIGN KEY (categories_id)
REFERENCES categories_description (categories_id) ,
Mit INDEX wird einfach mal ein Index auf das betreffende Feld gesetzt, welches den Schlüssel für das Verknüpfen der Tabellen enthält. Mit einem CONSTRAINT hat man nun die Möglichkeit den Fremdschlüssel zu definieren. REFERENCES gibt hierbei an, in welcher Tabelle und welcher Spalte sich der Fremdschlüssel befindet. Befindet sich die Tabelle in einer anderen Datenbank, kann dies natürlich auch definiert werden. Der Name der Datenbank mit einem Punkt einfach vor dem Tabellennamen geschrieben: DBNAME.TABLENAME. In dem Beispiel ist also categories_description die Tabelle die wir über categories_id verknüpfen wollen. Also ist bluegate_seo_url.categories_id == categories_description.categories_id. Sollte dies bei einem Datensatz nicht der Fall sein, so erscheint eine Fehlermeldung. Mit den Relationen wird also zugleich für eine schöne Datenkonsistenz gesorgt.
PS: Indizes ist die Mehrzahl von Index.
