2009-11-21 11 views
6

Ich habe in letzter Zeit über meine Datenbank-Indizes nachgedacht, in der Vergangenheit habe ich sie einfach nicht-chällig als nachträglicher Einfall geworfen und nie wirklich darüber nachgedacht, ob sie korrekt sind oder sogar helfen. Ich habe widersprüchliche Informationen gelesen, einige sagen, dass mehr Indizes besser sind und andere, dass zu viele Indizes schlecht sind, also hoffe ich, etwas Klärung zu bekommen und ein bisschen hier zu lernen.Benötigen Sie eine kleine Erklärung zu MySQL Indexe

Lassen Sie uns sagen, ich habe diese hypothetische Tabelle:

CREATE TABLE widgets (
    widget_id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    widget_name VARCHAR(50) NOT NULL, 
    widget_part_number VARCHAR(20) NOT NULL, 
    widget_price FLOAT NOT NULL, 
    widget_description TEXT NOT NULL 
); 

Ich würde in der Regel einen Index für die Felder hinzufügen, die verbunden werden und Felder, die auf den meisten häufig sortiert werden:

ALTER TABLE widgets ADD INDEX widget_name_index(widget_name); 

So, jetzt in einer Abfrage, wie zB:

SELECT w.* FROM widgets AS w ORDER BY w.widget_name ASC 

Die widget_name_index wird verwendet, um sor t das Ergebnisset.

Nun, wenn ich hinzufügen, einen Suchparameter:

SELECT w.* FROM widgets AS w 
WHERE w.widget_price > 100.00 
ORDER BY w.widget_name ASC 

Ich glaube, ich einen neuen Index benötigen.

ALTER TABLE widgets ADD INDEX widget_price_index(widget_price); 

Aber wird es beide Indizes verwenden? Wie ich es verstehe wird es nicht ...

ALTER TABLE widgets ADD INDEX widget_price_name_index(widget_price, widget_name); 

Jetzt wird widget_price_name_index sowohl die Datensätze auswählen und Reihenfolge verwendet werden. Aber was, wenn ich möchte es umdrehen und dies tun:

SELECT w.* FROM widgets AS w 
WHERE w.widget_name LIKE '%foobar%' 
ORDER BY w.widget_price ASC 

Wird widget_price_name_index dafür verwendet werden? Oder brauche ich auch eine widget_name_price_index?

ALTER TABLE widgets ADD INDEX widget_name_price_index(widget_name, widget_price); 

Was nun, wenn ich ein Suchfeld, die widget_name, widget_part_number und widget_description sucht?

Und was ist, wenn Endbenutzer nach jeder Spalte sortieren können? Es ist leicht zu sehen, wie ich mehr als ein Dutzend Indizes für nur 5 Spalten bekommen könnte.

Wenn wir eine weitere Tabelle hinzufügen:

CREATE TABLE specials (
    special_id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    widget_id INT UNSIGNED NOT NULL, 
    special_title VARCHAR(100) NOT NULL, 
    special_discount FLOAT NOT NULL, 
    special_date DATE NOT NULL 
); 
ALTER TABLE specials ADD INDEX specials_widget_id_index(widget_id); 
ALTER TABLE specials ADD INDEX special_title_index(special_title); 

SELECT w.widget_name, s.special_title 
FROM widgets AS w 
INNER JOIN specials AS s ON w.widget_id=s.widget_id 
ORDER BY w.widget_name ASC, s.special_title ASC 

Ich gehe davon aus das widget_id_index und die widgets.widget_id Primärschlüsselindex für die Verbindung verwenden, aber was ist die Sortierung? Wird es sowohl widget_name_index als auch special_title_index verwenden?

Ich möchte nicht zu lange herumlaufen, es gibt eine endlose Anzahl von Szenarien, die ich nachvollziehen könnte. Offensichtlich kann dies mit realen Szenarien viel komplexer werden als mit ein paar einfachen Tabellen. Jede Klärung wäre erwünscht.

+4

Ich werde dies nicht als eine Antwort, da ich kein Profi bin, wenn es um Datenbanken geht, aber in Mysql können Sie EXPLAIN vor einer Abfrage verwenden, um einige Informationen zu geben, welche Indizes verwendet werden. http://dev.mysql.com/doc/refman/5.0/en/explain.html – MitMaro

Antwort

5

Nach den bewährten Methoden müssen Sie beim Definieren der Tabellenschaltpläne keinen Index erstellen. Es ist immer besser, einen Index zu erstellen, wenn Sie die Abfragen in Ihrer Anwendung erstellen. In den meisten Fällen werden Sie mit einem einspaltigen Index beginnen, um eine Abfrage zu erfüllen. Wenn Sie viele Spalten in einer Abfrage verwenden möchten, können Sie einen abdeckenden Index erstellen.

Ein Deckungsindex ist ein Index mit zwei oder mehr Spalten. Wenn der Index alle Spaltenanforderungen einer Abfrage erfüllt, kann die Speicher-Engine alle Ergebnisse aus dem Index abrufen, anstatt eine Platten-E/A-Operation auszuführen. Wenn Sie also eine Abfrage erstellen, die mehr Spalten verwendet, können Sie entweder einen neuen Index erstellen, der alle erforderlichen Spalten enthält, oder Sie können den vorhandenen Index erweitern, um weitere Spalten einzubeziehen.

Sie müssen einige Überlegungen bei der Durchführung einer der oben genannten Überlegungen beachten. MySQL berücksichtigt einen Index nur, wenn die Spalte ganz links des Index in der Abfrage verwendet werden kann. Andernfalls wird einfach die gesamte Tabelle zum Abrufen von Ergebnissen gesucht. Wenn Sie also einen vorhandenen Index erweitern können, ohne alle Abfragen zu beeinflussen, die diesen Index verwenden, wäre dies eine gute Wahl. Andernfalls können Sie einen neuen Index für die neue Abfrage erstellen. Manchmal können die Abfragen angepasst werden, um sich an die Indexstruktur anzupassen.

+0

'anstelle einer Festplatten-E/A-Operation 'Wo werden Indexdaten gespeichert? –

3

Ein Index beschleunigt die Auswahl, verlangsamt jedoch die Einfügungen und Aktualisierungen. Sie müssen keinen Index für jede mögliche Kombination von Spalten erstellen, die Sie sich vorstellen können. Ich erstelle normalerweise nur die offensichtlichen Indizes, von denen ich weiß, dass sie häufig verwendet werden, und füge nur mehr hinzu, wenn ich nach Durchführung von Leistungsmessungen sehen kann, dass sie benötigt werden.Die Datenbank kann weiterhin einen Index verwenden, auch wenn nicht alle Spalten in der Abfrage abgedeckt sind.

+0

Weitere Indizes können besser sein. Zu viele Indizes sind definitiv schlechter. –

3

In einer Abfrage wird immer nur ein Index verwendet. Glücklicherweise können Sie einen Index die für mehrere Spalten erstellen:

ALTER TABLE widgets ADD INDEX name_and_price_index(widget_name, widget_price); 

Der obige Index verwendet werden, wenn Sie SELECT durch WIDGET_NAME oder WIDGET_NAME + widget_price (aber nicht nur widget_price).

Wie MitMaro darauf hinweist, verwenden Sie EXPLAIN für eine Abfrage, um zu sehen, welche Indizes MySQL zu wählen hat und welchen Index es verwendet. Weitere Details finden Sie unter here.

+0

Neueste Versionen von MySQL verfügen über eine Indexzusammenführung, die in einigen Fällen mehrere Indizes verwenden kann. – peufeu

Verwandte Themen