Mit MySQL können Sie einen Präfixindex definieren, dh, Sie definieren die ersten N Zeichen der zu indizierenden Originalzeichenfolge. Der Trick besteht darin, eine Zahl N zu wählen, die lang genug ist, um eine gute Selektivität zu erzielen, aber kurz genug, um Platz zu sparen. Das Präfix sollte lang genug sein, um den Index fast so nützlich zu machen, als ob Sie die gesamte Spalte indiziert hätten.
Bevor wir weitermachen, lassen Sie uns einige wichtige Begriffe definieren. Die Indexselektivität ist das Verhältnis der gesamten indizierten Werte und der Gesamtanzahl der Zeilen . Hier ist ein Beispiel für eine Testtabelle:
+-----+-----------+
| id | value |
+-----+-----------+
| 1 | abc |
| 2 | abd |
| 3 | adg |
+-----+-----------+
Indizieren wir nur das erste Zeichen (N = 1), sieht die Indextabelle wie folgt aus:
+---------------+-----------+
| indexedValue | rows |
+---------------+-----------+
| a | 1,2,3 |
+---------------+-----------+
In diesem Fall ist die Indexselektivität gleich IS = 1/3 = 0,33.
Lassen Sie uns nun sehen, was passieren wird, wenn wir die Anzahl der indizierten Zeichen auf zwei erhöhen (N = 2).
+---------------+-----------+
| indexedValue | rows |
+---------------+-----------+
| ab | 1,2 |
| ad | 3 |
+---------------+-----------+
In diesem Szenario ist IS = 2/3 = 0,66, was bedeutet, dass wir die Indexselektivität erhöht haben, aber wir haben auch die Größe des Index erhöht. Der Trick besteht darin, die minimale Zahl N zu finden, die zu maximaler Indexselektivität führt .
Es gibt zwei Ansätze, mit denen Sie Berechnungen für Ihre Datenbanktabelle durchführen können. Ich werde auf diesem Datenbank-Dump demonstrieren .
Lassen Sie uns sagen , dass wir Spalte hinzufügen möchten last_name in der Tabelle Mitarbeiter auf den Index, und wir wollen die kleinste Zahl definieren , N , die die beste Index Selektivität produzieren.
Lassen Sie uns zuerst die häufigsten Nachnamen identifizieren:
select count(*) as cnt, last_name from employees group by employees.last_name order by cnt
+-----+-------------+
| cnt | last_name |
+-----+-------------+
| 226 | Baba |
| 223 | Coorg |
| 223 | Gelosh |
| 222 | Farris |
| 222 | Sudbeck |
| 221 | Adachi |
| 220 | Osgood |
| 218 | Neiman |
| 218 | Mandell |
| 218 | Masada |
| 217 | Boudaillier |
| 217 | Wendorf |
| 216 | Pettis |
| 216 | Solares |
| 216 | Mahnke |
+-----+-------------+
15 rows in set (0.64 sec)
Wie Sie sehen, ist der Nachname Baba der häufigste. Jetzt werden wir die am häufigsten vorkommenden Nachnamen- Präfixe finden, beginnend mit Präfixen aus fünf Buchstaben.
+-----+--------+
| cnt | prefix |
+-----+--------+
| 794 | Schaa |
| 758 | Mande |
| 711 | Schwa |
| 562 | Angel |
| 561 | Gecse |
| 555 | Delgr |
| 550 | Berna |
| 547 | Peter |
| 543 | Cappe |
| 539 | Stran |
| 534 | Canna |
| 485 | Georg |
| 417 | Neima |
| 398 | Petti |
| 398 | Duclo |
+-----+--------+
15 rows in set (0.55 sec)
Es gibt viel mehr Vorkommen für jedes Präfix, was bedeutet, dass wir die Zahl N erhöhen müssen, bis die Werte fast dieselben sind wie im vorherigen Beispiel.
Hier sind Ergebnisse für N = 9
select count(*) as cnt, left(last_name,9) as prefix from employees group by prefix order by cnt desc limit 0,15;
+-----+-----------+
| cnt | prefix |
+-----+-----------+
| 336 | Schwartzb |
| 226 | Baba |
| 223 | Coorg |
| 223 | Gelosh |
| 222 | Sudbeck |
| 222 | Farris |
| 221 | Adachi |
| 220 | Osgood |
| 218 | Mandell |
| 218 | Neiman |
| 218 | Masada |
| 217 | Wendorf |
| 217 | Boudailli |
| 216 | Cummings |
| 216 | Pettis |
+-----+-----------+
Hier sind Ergebnisse für N = 10.
+-----+------------+
| cnt | prefix |
+-----+------------+
| 226 | Baba |
| 223 | Coorg |
| 223 | Gelosh |
| 222 | Sudbeck |
| 222 | Farris |
| 221 | Adachi |
| 220 | Osgood |
| 218 | Mandell |
| 218 | Neiman |
| 218 | Masada |
| 217 | Wendorf |
| 217 | Boudaillie |
| 216 | Cummings |
| 216 | Pettis |
| 216 | Solares |
+-----+------------+
15 rows in set (0.56 sec)
Das sind sehr gute Ergebnisse. Dies bedeutet, dass wir einen Index für die Spalte Nachname erstellen können, wobei nur die ersten 10 Zeichen indiziert werden. In der Tabellendefinitionsspalte ist Nachname als definiert. VARCHAR(16)
Dies bedeutet, dass wir 6 Bytes (oder mehr, wenn der Nachname UTF8-Zeichen enthält) pro Eintrag gespeichert haben. In dieser Tabelle gibt es 1637 verschiedene Werte, multipliziert mit 6 Bytes, was ungefähr 9 KB entspricht. Stellen Sie sich vor, wie diese Zahl wachsen würde, wenn unsere Tabelle Millionen von Zeilen enthält.
Sie können andere Methoden zum Berechnen der Anzahl von N in My Post Prefixed-Indizes in MySQL lesen .
Die Verwendung von MD5- und SHA1-Funktionen zur Erzeugung von Werten, die indiziert werden sollen, ist ebenfalls kein guter Ansatz . Warum? Read it in post So wählen Sie den richtigen Datentyp für einen Primärschlüssel in einer MySQL-Datenbank aus