Допустим, у меня есть таблица с полями A
и B
. Я делаю регулярные запросы на A
+ B
, поэтому я создал составной индекс на (A,B)
. Будут A
ли полностью оптимизированы запросы только по составному индексу?
Кроме того, я создал индекс A
, но Postgres по-прежнему использует составной индекс только для запросов A
. Если предыдущий ответ положительный, я думаю, это не имеет значения, но почему он выбирает составной индекс по умолчанию, если A
доступен один индекс?
explain analyze
и текст запроса?Ответы:
Это определенно. Мы обсудили это очень подробно под этим связанным вопросом:
Пространство выделяется в виде кратного числа
MAXALIGN
, которое обычно составляет 8 байт в 64-разрядной ОС или (гораздо реже) 4 байта в 32-разрядной ОС. Если вы не уверены, проверьтеpg_controldata
. Это также зависит от типов данных индексированных столбцов (некоторые требуют заполнения выравнивания) и фактического содержимого.Индекс, скажем, для двух
integer
столбцов (по 4 байта в каждом) обычно заканчивается точно таким же большим, как индекс только для одного, где еще 4 байта теряются при заполнении выравнивания.В таком случае у планировщика запросов действительно нет недостатка в использовании индекса
(a,b)
- по сравнению с индексом только(a)
. И, как правило, для нескольких запросов предпочтительно использовать один и тот же индекс. Вероятность того, что он (или его части) окажется в (быстром) кэше, при совместном использовании возрастает.Если вы уже поддерживаете индекс
(a,b)
, тогда не имеет смысла создавать другой индекс просто(a)
- если только он существенно не меньше. То же самое не относится к(b,a)
против(a)
. Перейдите по ссылке в первой строке, чтобы узнать больше.Если исходить из противоположного направления, когда вам нужен дополнительный индекс, подобный этому
(a,b)
, подумайте о том, чтобы сбросить существующий индекс просто(a)
- если это возможно. Часто это невозможно, поскольку это индекс PK илиUNIQUE
ограничения. Начиная с Postgres 11 вы можете просто добавитьb
к определению ограниченияINCLUDE
вместо этого предложение. Подробности в руководстве.Или создайте новый индекс
(b,a)
вместо этого, чтобы покрыть запросы толькоb
дополнительно. Только для условий равенства порядок индексных выражений в индексах btree не имеет значения. Тем не менее, при использовании условий дальности. Видеть:Есть потенциальные недостатки включения дополнительных столбцов в индекс, даже если он использует только пробел, в противном случае теряется при заполнении выравнивания:
Подробнее о горячих обновлениях:
Как измерить размеры объекта:
источник
По вашему вопросу у вас есть таблица с полями A и B. Если ваш запрос:
Оптимизатор выберет составной индекс, чтобы избежать извлечения произвольного доступа!
источник
Это в том случае, если вы просто используете только первый в предикате.
Будет выполнено сканирование, если вы используете первые столбцы составного ключа и неключевой столбец составного ключа.
Чтобы обмануть это, вы можете просто использовать фиктивные предикаты, такие как этот, а затем неключевой столбец:
[A, B] ваш индекс, [C] - еще один столбец
Чтобы использовать индекс, вы пишете как:
Он будет использовать индекс только в том случае, если есть один или два предиката [A] или [A], [B]. Он не будет использовать его в порядке [B], [A] или [A], [C]. Чтобы иметь возможность использовать индекс с дополнительным столбцом [C], необходимо принудительно использовать индекс, упорядочив предикаты как [A], [B] и [C].
источник
B=B
? Я думаю, что вы ничего не добились, поэтому я голосую за отсутствие каких-либо доказательств, которые не просто игнорирует оптимизаторB=B
фактически так же, какB IS NOT NULL
, что кажется невостребованным для. Конечно, не нужно использовать индекс на(a,b)
.