Arhn - архитектура программирования

PostgreSQL не будет использовать индекс для проекции, если индексы использовались для запросов.

Я провел несколько экспериментов, и утверждение в заголовке кажется верным, я хотел бы знать, есть ли способ обойти это.

Вот пример:

CREATE TABLE test ( cond text, v1 integer, v2 integer, v3 integer );
-- Insert millions of rows
CREATE INDEX cond_idx ON test (cond);
CREATE INDEX values_idx ON test (v1, v2, v3);
VACUUM ANALYZE test;

Выполнение этих запросов:

-- Uses Index Only Scan on values_idx for projection
SELECT sum(v1), sum(v2), sum(v3) FROM test;
-- Uses Bitmap Index Scan on cond_idx then a Bitmap Heap Scan
-- This is undesirable as it doesn't rely exclusively on indexes
SELECT sum(v1), sum(v2), sum(v3) FROM test WHERE cond = '123';

PostgreSQL может эффективно комбинировать индексы, но, похоже, только для составных условий. Есть ли способ заставить PostgreSQL использовать индекс для проекции после того, как он использовал одну или несколько для поиска необходимых строк?

Автоматическим ответом будет создание единого индекса со всеми 4 столбцами. Дело в том, что это всего лишь минималистичный пример. В реальном сценарии одна и та же таблица будет запрашиваться разными столбцами, требующими многостолбцовых индексов для каждого необходимого условия запроса.

ОБНОВЛЕНИЕ: счетчик изменен на сумму, чтобы сделать пример более понятным. Также добавлено больше столбцов «значение».


  • Может я старомоден, но ИМХО таблица без первичного ключа бессмысленна. Два свободных индекса ничего не изменят. 04.05.2015
  • У него также может быть первичный ключ, просто он не имеет отношения к примеру. 04.05.2015
  • Это ваше мнение. ИМХО критично. 04.05.2015

Ответы:


1

Агрегат count() не может использовать данные индекса в качестве входных данных, поскольку он считает 1 для каждого значения, отличного от null: http://www.postgresql.org/docs/9.4/static/functions-aggregate.html

count(expression): 
    number of input rows for which the value of expression is not null

Во втором запросе после фильтрации индекса мы не знаем, в какой строке есть нулевой столбец value.

Вам просто нужно добавить соответствующие данные в свой индекс и использовать индекс с несколькими столбцами.

CREATE INDEX cond_value_idx ON test (cond, value);

Это станет ясно, когда вы прочитаете отличный http://use-the-index-luke.com/

Вот аналогия, чтобы получить лучшее представление о внутреннем устройстве PostgreSQL. У вас есть 1000 обычных книг и 2 «специальных» книги. 1000 книг — это ваши строки, две другие — ваши индексы.

В одной из указателей перечислены все книжные полки и номера, классифицированные по темам, в другой перечислены все книжные полки и номера, но классифицированные по авторам.

Обратите внимание, что 1000 книг хранятся на огромной полке, а две индексные книги лежат на вашем столе, готовые к использованию.

Проблема в том, что некоторые книги настолько уникальны, что не классифицируются по темам (наши нулевые значения).

Если вы хотите подсчитать книги, связанные с темой, вам нужно выбрать только индекс «тема». Но если вы хотите подсчитать все книги Грегори Смита, связанные с темой, вам нужно найти книги Грегори Смита в указателе авторов, а затем взять их с полки, чтобы узнать, есть ли у них тема.

Решением здесь является третья индексная книга, в которой перечислены все книжные полки и номера, классифицированные по авторам, а затем по темам. Только тогда вы сможете ответить на вопрос сразу, не подходя к полкам.

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

03.05.2015
  • Хорошее объяснение. Важно то, что список всех 1000 книг по темам бесполезен для вас, когда вы уже сузили список до 10 книг определенного автора — вам придется читать каждую страницу указателя, чтобы найти, где находятся эти 10 книг. книги помещаются, что было бы не быстрее, чем подойти к полке и посмотреть на них. 04.05.2015
  • Спасибо за ответ, вопрос заключался в том, как добиться этого без индекса, включающего как условие, так и проекцию. Как я сказал в конце, в реальном сценарии проекция будет иметь много столбцов, и есть запросы с условиями, которые также зависят от разных столбцов. Для вашего подхода требуется индекс столбцов условия+проекции для каждого необходимого условия. PostgreSQL может эффективно комбинировать несколько индексов, но, похоже, не для проекций. 04.05.2015
  • О, я понял, извините за неправильный ответ. Я боюсь, что эта функция еще не реализована в postgresql, но даже если бы она была, я предполагаю, что многие проекции по-прежнему будут использовать сканирование таблиц. Причина в том, что использование индекса далеко не бесплатная операция. С btrees мой типичный индекс составляет 1/10 ~ 1/5 размера фактической таблицы, вплоть до размера самой таблицы в редких и крайних случаях. Это означает, что с 5 или более проекциями наиболее эффективным решением (с точки зрения памяти) является сканирование таблицы. В любом случае невозможно использовать индексы для проекций с предложением where, как объясняется в моем ответе. 04.05.2015
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..