Чи потрібен індекс для первинного ключа в SQLite?


130

Коли цілий стовпець позначений як первинний ключ у таблиці SQLite, чи повинен явно також створюватися індекс для нього? Здається, SQLite не автоматично створює індекс для стовпця первинного ключа, але, можливо, він все-таки індексує його, враховуючи його призначення? (Я буду шукати в цій колонці весь час).

Чи відрізняється ситуація для первинного ключа рядка?

Відповіді:


149

Це робить це за вас.

У стовпчиках INTEGER PRIMARY KEY, як UNIQUE, так і PRIMARY KEY, обмеження реалізуються шляхом створення індексу в базі даних (так само, як і в заяві "CREATE UNIQUE INDEX"). Такий індекс використовується, як і будь-який інший індекс у базі даних для оптимізації запитів. Як наслідок, часто немає переваги (але суттєвих накладних витрат) у створенні індексу на наборі стовпців, які вже колективно підпадають під УНІКАЛЬНЕ або ПЕРВИЧНЕ КЛЮЧОВЕ обмеження.


8
Дійсно, він говорить: "Атрибут PRIMARY KEY зазвичай створює УНІКАЛЬНИЙ індекс на стовпчику або стовпцях, які вказані як PRIMARY KEY". Однак цей індекс не видно в програмах управління SQLite, ось чому я запитав.
Marek Jedliński

1
Це згадування в sqlite_masterтаблиці з назвою, що починається з sqlite_autoindex_.
dan04

2
Пізно, але @NicolasZozol так, вам потрібно створити UNIQUEіндекс (або UNIQUEобмеження) для батьківських / посилальних полів, якщо його немає; то рекомендується , щоб дитина / посилається поле (s) має індекс (який , як правило , НЕ буде унікальний): тут бачить
TripeHound

2
Хм, розділ SQL Data Constraints тут говорить: У більшості випадків УНІКАЛЬНІ та ПЕРВИЧНІ КЛЮЧОВІ обмеження реалізуються шляхом створення унікального індексу в базі даних. (Винятки становлять INTEGER PRIMARY KEY та PRIMARY KEYs BEO ROWID таблиць.). Тож відповідь не завжди правдива?
Грайлива цікавість

3
Схоже, що rowid IS індексований, але реалізований інакше sqlite.org/lang_createtable.html#rowid Дані для таблиць rowid зберігаються як структура B-Tree, що містить один запис для кожного рядка таблиці, використовуючи значення rowid як ключове ... Пошук для запису з певним рядком ... є приблизно вдвічі швидшим, ніж аналогічний пошук, зроблений шляхом вказівки будь-якого іншого ПЕРВИЧНОГО КЛЮЧА чи індексованого значення.
матрешкін

15

Якщо стовпець позначений INTEGER PRIMARY KEY, це фактично приблизно вдвічі швидше аналогічного пошуку, вказуючи будь-який інший PRIMARY KEY або індексоване значення . Це відбувається тому:

... всі рядки в таблицях SQLite мають 64-розрядний цілочисельний підписаний ключ, який однозначно ідентифікує рядок у його таблиці ... Пошук записів із певним рядком, або для всіх записів із рядками в заданому діапазоні, становить приблизно вдвічі швидко, як аналогічний пошук, зроблений шляхом вказівки будь-якого іншого ПЕРВИЧНОГО КЛЮЧА чи індексованого значення.

За одним винятком, зазначеним нижче, якщо рядна таблиця має первинний ключ, що складається з одного стовпця, а оголошений тип цього стовпця - "INTEGER" у будь-якій суміші верхнього та нижнього регістру, то стовпець стає псевдонімом для rowid.

Такий стовпець зазвичай називають "цілим первинним ключем". Стовпець PRIMARY KEY стає цілим первинним ключем лише тоді, коли оголошене ім'я типу точно "INTEGER". Інші цілі назви типу цілих чисел, такі як "INT" або "BIGINT" або "SHORT INTEGER" або "UNSIGNED INTEGER", призводять до того, що стовпчик первинного ключа поводиться як звичайний стовпець таблиці з цілим спорідненістю та унікальним індексом, а не як псевдонім для rowid.

Дивіться: http://www.sqlite.org/lang_createtable.html#rowid


8

База даних завжди мовчки створюватиме індекс унікального первинного ключа, щоб він міг внутрішньо перевірити, чи він унікальний ефективно.

Створивши його, він використовуватиме його при необхідності.

Звичайно, це не завжди буде кластеризовано, і ви зазвичай вказуєте в схемі, якщо ви хочете, щоб це було.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.