#django #postgresql #postgresql-9.5 #database-indexes #django-1.9
#django #postgresql #postgresql-9.5 #база данных-индексы #django-1.9
Вопрос:
У меня есть настройка Django-Postgres с этой таблицей —
class User(models.Model):
id = models.CharField(max_length=255, primary_key=True)
Запуск миграции создает два индекса в поле (что автоматически делает Django, как я проверил при запуске sqlmigrate
) — один индекс для pkey и один для varchar_pattern_ops
—
d "user";
Column| Type | Modifiers | Storage | Stats target | Description
------ -------------------------- ----------- ---------- -------------- -------------
id | character varying(255) | not null | extended | |
Indexes:
"user_pkey" PRIMARY KEY, btree (id)
"user_id_90845346_like" btree (id varchar_pattern_ops)
Насколько я понимаю, если я выполню этот запрос
select * from "user" where id='id1234';
он должен использовать user_pkey
. Вместо этого он использует user_id_90845346_like
.
explain analyze select * from "user" where id='id1234';
Index Scan using "user_id_90845346_like" on "user" (cost=0.41..8.43 rows=1 width=770) (actual time=0.033..0.0
33 rows=0 loops=1)
Index Cond: ((id)::text = 'id1234'::text)
Planning time: 1.335 ms
Execution time: 0.072 ms
(4 rows)
Я также не вижу возможности заставить Postgres использовать индекс, но на самом деле я хочу знать, почему =
поиск не использует первичный ключ. Разве при like text%
поиске не следует использовать varchar_pattern_ops
индекс?
Ответ №1:
Драйвер postgres всегда будет выбирать varchar_pattern_ops
индекс, если он существует, в случаях, когда столбец, по которому вы индексируете, является столбцом varchar или каким-либо его вариантом. Проще говоря, поскольку ваш столбец, который вы индексируете, содержит строки, драйвер выберет индекс, который лучше всего работает со строками, когда он доступен. Если вместо этого вы сохранили первичные ключи в виде целых чисел, драйвер будет использовать btree
индекс.