Cheatah: mySQL: Wieviele Indizes verwendet mySQL pro Tabelle und Abfrage

Beitrag lesen

Hi,

Wenn ich mit zwei Indexzugriffen jeweils 0.0001% der Datensatzmenge
isolieren und dies dann mit sich selbst JOINen könnte, dann wäre das
rasend schnell, verglichen mit einem full table scan.

das ist richtig, nur sprechen zwei Gründe dagegen:

1.) ist es (bei "handelsüblicher" Datenmenge einer privaten Website) sehr unwahrscheinlich, eine solche Erfolgsquote zu haben; trotz günstigster Indizes. In der Regel wird ein _guter_ Index rund 10% der Daten zurückliefern - unterschiedliche Indizes bringen sich kaum überschneidende Mengen, die zu JOINen nicht mehr effizient über eine Bitmap lösbar ist. Der Organisationsaufwand hierzu, verbunden mit dem Organisationsaufwand der Suche nach dem passenden Index, ist hoch.

2.) weiß die Datenbank normalerweise nicht, ob ein Index (und wenn ja, welcher) derartige Erfolge liefern kann; denn wenn er bei der einen Abfrage 1% der Daten liefert, liefert er bei einer anderen vielleich 99%. Zwar kann man dazu statistische Analysen durchführen; aber selbst Oracle, bei dem sowas gang und gäbe ist und das mit Datenmassen immenser Größe vertraut ist, erlaubt pro Tabellenabfrage nur einen Index.

Ich würde von keinem DBMS erwarten, dass es, nur weil es "bei dieser Abfrage zufällig sinnvoll ist", Dinge tut, von denen selbst die mächtigsten Systeme Abstand nehmen.

Wenn Du mehrere Indizes für sinnvoll hälst, hast Du den Fehler
gemacht, sie nur einspaltig anzulegen.

Vielleicht. Meistens sogar. Aber nicht immer.

Natürlich nicht immer. Meistens eben.

SELECT <fields> FROM <tablename>
WHERE <field1> LIKE 'x%'
   AND <field2> LIKE 'y%';

Bilde das mal mit einem einzigen Index über beiden Spalten nach ...

Oracle:

SQL> create index testindex on bak_category (name, normalized_name);
Index wurde angelegt.
SQL> set autotrace traceonly explain
SQL> select * from bak_category where name like 'x%' and normalized_name like 'y%';

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'BAK_CATEGORY'
   2    1     INDEX (RANGE SCAN) OF 'TESTINDEX' (NON-UNIQUE)

Also, der Index wird verwendet. Ich kann natürlich nicht dafür sprechen, dass MySQL das auch tut :-)

Cheatah