@BadWolf:
SQLite verwendet schon Datentypen, bloss nicht pro Spalte sondern pro Wert. D.h. Integers stehen nicht als String in der DB, sondern wirklich als "echte" Integer.
Es geht aber primär um die Grösse der Index-Einträge, und Strings können eben im Vergleich zu Integers recht gross werden.
@Unix-Tom:
Wieso Index neu anlegen? Das ist ein B-Baum, da wird einfach eingefügt/rausgelöscht, und nicht jedes mal der Index neu angelegt.
Klar, je grösser die Keys sind, desto mehr Daten müssen beim Einfügen/Rauslöschen rumgeschoben werden, desto mehr IO Kosten fallen an.
Ist aber bei SELECT grundsätzlich das selbe. Je grösser der Index, desto tiefer wird er, desto länger dauert das SELECT.
Schwierig werden Performance-Abschätzungen halt u.A. dadurch, dass die Datenbank nen Cache verwendet. So lange der Index komplett in den Cache passt, wird man bei einfachen SELECTs kaum nen Unterschied merken.
Wenn es aber mal soweit ist, dass der Index eben nicht mehr komplett in den Cache passt, dann bricht die Performance rasant ein. Und an dem Punkt ist man eben schneller, je grösser die Index Keys sind.
Und selbst wenn man nen String-Index der nicht mehr in den Cache passt mit einem Integer-Index der nicht mehr in den Cache passt vergleicht, wird immer noch der Integer-Index schneller sein. Weil er eben immer noch kleiner ist. D.h. er hat weniger Ebenen, und auch der Hit/Miss Ratio wird immer noch besser aussehen als mit dem String Index.
Ein weiterer Punkt der Performance kosten kann sind die String-Vergleiche selbst. Nämlich dann, wenn man mit einer "nicht trivialen" Collation arbeitet. Also z.B. irgendwas was case-insensitive ist. Oder auch nur Unicode-Collations die verschiedene binäre Darstellungen des selben Strings als "gleiche" behandelt.
Dann werden die grösser/kleiner/gleich Vergleiche nämlich auf einmal ordentlich teuer. Wenn man dann über solche Spalten nen JOIN macht, kann das ordentlich zuschlagen.
Wobei sich das auch in einer Grössenordnung abspielt, die man nur merkt, wenn der Index komplett im Cache ist. Wenn wirklich physikalisch IO gemacht werden muss, dann geht das mehr oder weniger in den IO Kosten unter.
Bei SQLite ist das allerdings kein Thema, da SQLite einfach nicht "schlau genug" beim Strings Vergleichen ist.