Проекции (projections) в Vertica

Проекции (projections) используются в БД Vertica для ускорения выборок. Это просто копия данных, которые отсортированы/отфильтрованы/сгруппированы определенным образом.

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

В целом, проекция — это что-то похожее на индекс в обычной БД. За исключением того, что это полная копия данных. Да, проекции занимают место на диске (каждая новая — полная копия данных), однако дают огромный прирост в производительности. Это тот случай, когда стоимость жесткого диска дешевле времени.

Супер-проекция

У каждой таблицы по умолчанию всегда существует одна проекция. Она называется супер-проекцией. Она содержит данные в том виде, в котором были объявлены колонки при создании таблицы. Посмотреть список проекций таблицы можно так:

SELECT GET_PROJECTIONS('test');

# Покажет проекции таблицы test

Создание проекций

Представим, что у нас есть таблица test c двумя колонками:

test
id | name

И мы выполняем такой запрос:

SELECT * FROM test WHERE name = 'Den'

Посчитаем стоимость выполнения запроса (оценка сложности):

EXPLAIN SELECT * FROM test WHERE name = 'Den'

Покажет:

Access Path:
 +-STORAGE ACCESS for test_super [Cost: 12K, Rows: 503] (PATH ID: 1)
 |  Projection: public.test_super
 |  Materialize: test_super.name, test_super.id
 |  Filter: (test_super.name = 'Den'
...

# Оценка сложности запроса и использование проекции test_super

Супер-проекция плохо подойдет под этот запрос, т.к. придется просканить все записи в таблице для выборки подходящих.

Создадим проекцию, которая будет отсортирована по колонке name:

CREATE PROJECTION test_name_id AS SELECT name, id FROM test ORDER BY name;

# Создаем проекцию под запрос

Выполним синхронизацию данных:

SELECT start_refresh()

Теперь сравним стоимость выполнения запроса:

EXPLAIN SELECT * FROM test WHERE name = 'Den'
Access Path:
 +-STORAGE ACCESS for test [Cost: 210, Rows: 503] (PATH ID: 1)
 |  Projection: public.test_name_id
 |  Materialize: test.name, test.id
 |  Filter: (test.name = 'Den')
...

# Использование новой проекции при упрощении запроса

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


Подпишитесь на Хайлоад с помощью Google аккаунта
или закройте эту хрень