Является ли составной индекс полезным для запросов в первом поле?

Предположим, у меня есть таблица с полями A и B. Я делаю регулярные запросы на A + B, поэтому я создал составной индекс в (A,B). Запросы только на A также будут полностью оптимизированы с помощью составного индекса?

Кроме того, я создал индекс в A, но Postgres все еще использует составной индекс для запросов только A. Если предыдущий ответ положительный, я думаю, это не имеет большого значения, но почему он выбирает составной индекс по умолчанию, если доступен один индекс A?

69 голосов | спросил Luciano 23 +04002012-10-23T21:19:26+04:00312012bEurope/MoscowTue, 23 Oct 2012 21:19:26 +0400 2012, 21:19:26

3 ответа


75

Конечно. Мы подробно обсудили этот вопрос:

Пространство выделяется в кратном MAXALIGN, которое обычно составляет 8 байтов в 64-разрядной ОС или (менее распространенных) 4 байтах в 32-разрядной ОС. Если вы не уверены, отметьте pg_controldata . Это также зависит от типов данных индексированных столбцов (некоторые требуют выравнивания) и фактического содержимого.

Индекс, скажем, на два столбца integer, как правило, заканчивается таким же, как индекс на одном. Для всего одного integer (4 байта) добавляются еще 4 байта выравнивания.

В таком случае для планировщика запросов действительно нет недостатка в использовании индекса на (a,b) - по сравнению с индексом только для (a) , И, как правило, предпочтительно, чтобы несколько запросов использовали один и тот же индекс. Вероятность того, что он будет находиться в кеше уже (или его части), растет при совместном использовании.

Если вы уже поддерживаете индекс в (a,b), тогда нет смысла создавать другой индекс только для (a) - если это не существенно меньше. То же самое: not true для (b,a) vs. (a). Следуйте ссылке в первой строке, чтобы узнать больше об этом.

С другой стороны, существует потенциальный недостаток, заключающийся в добавлении дополнительных столбцов в индекс, даже если это использует только пространство, потерянное для выравнивания. Если дополнительный столбец обновляется, индекс нуждается в обновлении. Также предотвращает появление обновлений HOT (Heap Only Tuple) в таблице, когда этот столбец задействован.

Подробнее о обновлениях HOT:

Как измерять размеры объектов:

ответил Erwin Brandstetter 24 +04002012-10-24T02:49:45+04:00312012bEurope/MoscowWed, 24 Oct 2012 02:49:45 +0400 2012, 02:49:45
1

По вашему вопросу у вас есть таблица с полями A и B. Если у вас есть запрос:

SELECT * FROM [YOUR TBL]
WHERE A='XXXX'

Оптимизатор будет выбирать индекс Composite, чтобы избежать извлечения произвольного доступа!

ответил CAM 27 J0000006Europe/Moscow 2017, 13:30:06
-4

В случае, если вы просто используете только первое в предикате.

Он выполнит сканирование, если вы используете первые столбцы составного и неклассического столбцов составного ключа.

Чтобы обмануть его, вы можете просто фиктивные предикаты, подобные этому, а затем нек-ключ:

[A, B] - ваш индекс, [C] - другой столбец

Чтобы использовать индекс, который вы пишете как:

SELECT
    A,B,C,D,E
FROM 
    test
WHERE
   A=1
AND
   B=B
AND 
   C=3
  

... почему он выбирает составной индекс по умолчанию, если доступен один индекс A?

Он будет использовать индекс только в случае, если есть один или два предиката [A] или [A], [B]. Он не будет использовать его в порядке [B], [A] или [A], [C]. Чтобы иметь возможность использовать индекс с дополнительным столбцом [C], вам необходимо обеспечить индекс, упорядочив предикаты как [A], [B] и [C].

ответил Farfarak 24 +04002012-10-24T13:13:26+04:00312012bEurope/MoscowWed, 24 Oct 2012 13:13:26 +0400 2012, 13:13:26

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132