Wird für einen Primärschlüssel in SQLite ein Index benötigt?

130

Wenn eine Ganzzahlspalte in einer SQLite-Tabelle als Primärschlüssel markiert ist, sollte auch explizit ein Index dafür erstellt werden? SQLite scheint nicht automatisch einen Index für eine Primärschlüsselspalte zu erstellen, indiziert ihn aber möglicherweise trotzdem, je nach Zweck? (Ich werde die ganze Zeit in dieser Spalte suchen).

Wäre die Situation für einen String-Primärschlüssel anders?

Marek Jedliński
quelle

Antworten:

148

Es macht es für dich.

Abgesehen von den INTEGER PRIMARY KEY-Spalten werden sowohl UNIQUE- als auch PRIMARY KEY-Einschränkungen implementiert, indem ein Index in der Datenbank erstellt wird (genau wie bei einer Anweisung "CREATE UNIQUE INDEX"). Ein solcher Index wird wie jeder andere Index in der Datenbank verwendet, um Abfragen zu optimieren. Infolgedessen gibt es häufig keinen Vorteil (aber einen erheblichen Overhead) beim Erstellen eines Index für eine Reihe von Spalten, die bereits gemeinsam einer EINZIGARTIGEN oder PRIMÄREN SCHLÜSSEL-Einschränkung unterliegen.

hvgotcodes
quelle
8
In der Tat heißt es: "Das PRIMARY KEY-Attribut erstellt normalerweise einen EINZIGARTIGEN Index für die Spalte oder Spalten, die als PRIMARY KEY angegeben sind." Dieser Index ist jedoch in SQLite-Verwaltungsanwendungen nicht sichtbar. Deshalb habe ich gefragt.
Marek Jedliński
1
Es wird in der sqlite_masterTabelle mit einem Namen erwähnt, der mit beginnt sqlite_autoindex_.
dan04
2
Spät, aber @NicolasZozol Ja, Sie müssen einen UNIQUEIndex (oder eine UNIQUEEinschränkung) für die übergeordneten / referenzierten Felder erstellen, wenn diese nicht vorhanden sind. Es wird empfohlen, dass die untergeordneten / referenzierenden Felder einen Index haben (der normalerweise nicht eindeutig ist): siehe hier
TripeHound
2
Hmm, Abschnitt SQL Data Constraints hier sagt: In den meisten Fällen werden UNIQUE- und PRIMARY KEY-Einschränkungen implementiert, indem ein eindeutiger Index in der Datenbank erstellt wird. (Die Ausnahmen sind INTEGER PRIMARY KEY und PRIMARY KEYs für WITHOUT ROWID-Tabellen.) Die Antwort ist also nicht immer wahr?
Verspielte Neugier
3
Es scheint, als wäre die Zeilen-ID indiziert, aber anders implementiert. Sqlite.org/lang_createtable.html#rowid Die Daten für Zeilen-ID-Tabellen werden als B-Tree-Struktur gespeichert, die einen Eintrag für jede Tabellenzeile enthält, wobei der Zeilen-ID-Wert als Schlüssel verwendet wird für einen Datensatz mit einer bestimmten Zeilen-ID ... ist ungefähr doppelt so schnell wie eine ähnliche Suche, die durch Angabe eines anderen PRIMARY KEY oder eines indizierten Werts durchgeführt wird.
Matreshkin
15

Wenn eine Spalte mit INTEGER PRIMARY KEY markiert ist, ist sie ungefähr doppelt so schnell wie eine ähnliche Suche, bei der ein anderer PRIMARY KEY oder ein indizierter Wert angegeben wird . Das ist weil:

... Alle Zeilen in SQLite-Tabellen haben einen 64-Bit-Ganzzahlschlüssel mit Vorzeichen, der die Zeile in ihrer Tabelle eindeutig identifiziert. Die Suche nach einem Datensatz mit einer bestimmten Zeilen-ID oder nach allen Datensätzen mit Zeilen-IDs innerhalb eines bestimmten Bereichs ist ungefähr doppelt so hoch schnell wie eine ähnliche Suche, die durch Angabe eines anderen PRIMARY KEY oder eines indizierten Werts durchgeführt wird.

Mit einer unten angegebenen Ausnahme wird die Spalte zu einem Alias ​​für die Zeilen- ID, wenn eine Zeilen-ID-Tabelle einen Primärschlüssel hat, der aus einer einzelnen Spalte besteht und der deklarierte Typ dieser Spalte in einer beliebigen Mischung aus Groß- und Kleinbuchstaben "INTEGER" ist .

Eine solche Spalte wird üblicherweise als "ganzzahliger Primärschlüssel" bezeichnet. Eine PRIMARY KEY-Spalte wird nur dann zu einem ganzzahligen Primärschlüssel, wenn der deklarierte Typname genau "INTEGER" ist. Andere ganzzahlige Typnamen wie "INT" oder "BIGINT" oder "SHORT INTEGER" oder "UNSIGNED INTEGER" bewirken, dass sich die Primärschlüsselspalte wie eine normale Tabellenspalte mit ganzzahliger Affinität und einem eindeutigen Index verhält, nicht als Alias ​​für die Zeilen-ID.

Siehe: http://www.sqlite.org/lang_createtable.html#rowid

Eiffel
quelle
8

Eine Datenbank erstellt immer stillschweigend einen Index für einen eindeutigen Primärschlüssel, damit sie intern effizient überprüfen kann, ob er eindeutig ist.

Nachdem es erstellt wurde, wird es bei Bedarf verwendet.

Es wird natürlich nicht immer geclustert, und Sie geben normalerweise im Schema an, ob dies gewünscht wird.

Goldesel
quelle